OpenSSL 簡單思路和函數筆記

一直以來都是普通的socket read/write,如今終於有基於SSL通道的項目了。因此簡單記錄了一下OpenSSL的調用流程,便於快速入門。
本文地址:https://segmentfault.com/a/11...編程

Reference

OpenSSL流程和函數介紹

初始化

int SSL_Library_init (void);

選擇會話協議和建立會話環境

目前支持的會話協議包括:TLSv1.0, SSLv2, SSLv3, SSLv2/v3
OpenSSL中一個會話的環境稱爲「CTX」,申請CTX的函數是:segmentfault

SSL_CTX *SSL_CTX_new (SSL_METHOD *method);

其中method就是會話協議,好比SSLv2/v3的client,則傳入函數調用的返回值:框架

const SSL_METHOD *SSLv23_client_method (void);

接下來是設置CTX的屬性,好比制定證書驗證方式:異步

int SSL_CTX_set_verify (SSL_CTX *ctx, 
                        int mode, 
                        int (*verify_callback), 
                        int (X509_STROE_CTX *));

加載CA證書:socket

SSL_CTX_load_varify_location (SSL_CTX *ctx, const char *Cafile, const char *Capath);

加載用戶私鑰:tcp

SSL_CTX_use_Private_file (SSL_CTX *ctx, const char *file, int type);

加載用戶證書:函數

SSL_CTX_use_certificate_file (SSL_CTX *ctx, const char *file, int type);

驗證私鑰和證書是否相等.net

int SSL_CTX_check_private_key (SSL_CTX *ctx);

創建SSL套接字

SSL *SSL_new (SSL_CTX *ctx);

使用socket綁定SSL套接字:code

int SSL_set_fd (SSL *ssl, int fd);
int SSL_set_rfd (SSL *ssl, int fd);    // 只讀
int SSL_set_wfd (SSL *ssl, int fd);    // 只寫

注意:上述三個函數成功時返回TRUE,失敗時返回FALSEserver

完成SSL握手

int SSL_connect (SSL *ssl);        // 用於client
int SSL_accept  (SSL *ssl);        // 用於client

從SSL套接字中提取對方的證書信息

X509 *SSL_get_peer_certificate (SSL *ssl);

獲取證書全部者的名字:

X509_NAME *X509_get_subject_name (X509 *a);

數據傳輸

int SSL_read  (SSL *ssl, void *buf, int num);
int SSL_write (SSL *ssl, const void *buf, int num);

結束SSL通訊

關閉SSL套接字

int SSL_shitdown (SSL *ssl);

釋放SSL套接字

void SSL_free (SSL *ssl);

釋放SSL會話

void SSL_CTX_free (SSL_CTX *ctx);

OpenSSL應用編程框架

下面大體的僞代碼說明了調用SSL的一整個流程

Client端

ctx = SSL_CTX_new (SSLv23_client_method());
ssl = SSL_new (ctx);
fd = socket ();
connect ();
SSL_set_fd (ssl, fd);
SSL_connect (ssl);
SSL_write ();

Server端

ctx = SSL_CTX_new (SSLv23_server_method());
ssl = SSL_new (ctx);
fd = socket ();
bind ();
listen ();
accept ();
SSL_set_fd (ssl, fd);
SSL_accept (ssl);
SSL_read ();

注意

  • OpenSSL庫中,各個函數的返回值的格式並不統一(有些用0表示失敗,有些用0表示成功),請注意區分
  • 用在OpenSSL的fd不能設置爲nonblock,不然在SSL_connect時會失敗——感受這一點限制了OpenSSL與除了libevent以外其餘異步I/O庫的適配
  • 關於nonblock的問題,感謝@程序猿小何的補充:能夠在完成了SSL_connect/accept以後,將fd設置爲nonblock

姊妹篇

mbedTLS(PolarSSL)簡單思路和函數筆記

相關文章
相關標籤/搜索