一直以來都是普通的socket read/write,如今終於有基於SSL通道的項目了。因此簡單記錄了一下OpenSSL的調用流程,便於快速入門。
本文地址:https://segmentfault.com/a/11...編程
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_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
int SSL_connect (SSL *ssl); // 用於client int SSL_accept (SSL *ssl); // 用於client
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套接字
int SSL_shitdown (SSL *ssl);
釋放SSL套接字
void SSL_free (SSL *ssl);
釋放SSL會話
void SSL_CTX_free (SSL_CTX *ctx);
下面大體的僞代碼說明了調用SSL的一整個流程
ctx = SSL_CTX_new (SSLv23_client_method()); ssl = SSL_new (ctx); fd = socket (); connect (); SSL_set_fd (ssl, fd); SSL_connect (ssl); SSL_write ();
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 ();
nonblock
,不然在SSL_connect
時會失敗——感受這一點限制了OpenSSL與除了libevent
以外其餘異步I/O庫的適配nonblock
的問題,感謝@程序猿小何的補充:能夠在完成了SSL_connect/accept
以後,將fd設置爲nonblock