主要介紹openssl進(jìn)行SSL通信的一些函數(shù)以及過程,主要是初始化過程,至于數(shù)據(jù)的接收以及后續(xù)處理可以具體問題具體分析。
load所有的SSL算法
OpenSSL_add_ssl_algorithms();
建立SSL所用的method
SSL_METHOD *meth=SSLv23_method();
初始化上下文情景
SSL_CTX *ctx=SSL_CTX_new(meth);
ret->quiet_shutdown=1;默認(rèn)的是ret->quiet_shutdown=0;他相當(dāng)于SSL_set_shutdown函數(shù)將參數(shù)設(shè)置為SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN
當(dāng)設(shè)置為1時(shí),假如關(guān)閉后,不通知對方,這樣不適合TLS標(biāo)準(zhǔn)
SSL_CTX_set_quiet_shutdown(ctx,1);
ctx->options|=SSL_OP_ALL,SSL/TLS有幾個(gè)公認(rèn)的bug,這樣設(shè)置會(huì)使出錯(cuò)的可能更小
SSL_CTX_set_options(ctx,SSL_OP_ALL);
設(shè)置cache的大小,默認(rèn)的為1024*20=20000,這個(gè)也就是可以存多少個(gè)session_id,一般都不需要更改的。假如為0的話將是無限
SSL_CTX_sess_set_cache_size(ctx,128);
SSL_CTX_load_verify_locations用于加載受信任的CA證書,CAfile如果不為NULL,則他指向的文件包含PEM編碼格式的一個(gè)或多個(gè)證書,可以用e.g.來簡要介紹證書內(nèi)容
CApath如果不為NULL,則它指向一個(gè)包含PEM格式的CA證書的目錄,目錄中每個(gè)文件包含一份CA證書,文件名是證書中CA名的HASH值
可以用c-rehash來建立該目錄,如cd /some/where/certs(包含了很多可信任的CA證書) c_rehash .。返回一成功,0 失敗。SSL_CTX_set_default_verify_paths找尋默認(rèn)的驗(yàn)證路徑,在這里肯定找不到的。
這里主要set cert_store
char *CAfile=NULL,*CApath=NULL;
SSL_CTX_load_verify_locations(ctx,CAfile,CApath);
當(dāng)需要客戶端驗(yàn)證的時(shí)候,服務(wù)器把CAfile里面的可信任CA證書發(fā)往客戶端。
if(CAfile !=NULL )SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
設(shè)置最大的驗(yàn)證用戶證書的上級數(shù)。
SSL_CTX_set_verify_depth(ctx,10);
當(dāng)使用RSA算法鑒別的時(shí)候,會(huì)有一個(gè)臨時(shí)的DH密鑰磋商發(fā)生。這樣會(huì)話數(shù)據(jù)將用這個(gè)臨時(shí)的密鑰加密,而證書中的密鑰中做為簽名。
所以這樣增強(qiáng)了安全性,臨時(shí)密鑰是在會(huì)話結(jié)束消失的,所以就是獲取了全部信息也無法把通信內(nèi)容給解密出來。
static unsigned char dh512_p[]={
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
0x47,0x74,0xE8,0x33,
};
static unsigned char dh512_g[]={0x02,};
DH *dh=DH_new();
dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
SSL_CTX_set_tmp_dh(ctx,dh);
下面加載服務(wù)器的證書和私鑰,私鑰可以和證書在一個(gè)文件之中。判斷私鑰和證書是否匹配。
char *s_cert_file="server.pem";
char *s_key_file=NULL;
SSL_CTX_use_certificate_file(ctx,s_cert_file,SSL_FILETYPE_PEM);
獲取私鑰之前先把私鑰的密碼給寫上
char *pKeyPasswd="serve";
SSL_CTX_set_default_passwd_cb_userdata(ctx, pKeyPasswd);
SSL_CTX_use_PrivateKey_file(ctx,s_cert_file,SSL_FILETYPE_PEM);
SSL_CTX_check_private_key(ctx);
設(shè)置一個(gè)臨時(shí)的RSA,在出口算法中,有規(guī)定需要這么做的。
RSA *rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
SSL_CTX_set_tmp_rsa(ctx,rsa);
用于設(shè)置驗(yàn)證方式。s_server_verify是以下值的邏輯或
SSL_VERIFY_NONE表示不驗(yàn)證,SSL_VERIFY_PEER用于客戶端時(shí)要求服務(wù)器必須提供證書,用于服務(wù)器時(shí)服務(wù)器會(huì)發(fā)出證書請求消息要求客戶端提供證書,但是客戶端也可以不提供
SSL_VERIGY_FAIL_IF_NO_PEER_CERT只適用于服務(wù)器且必須提供證書。他必須與SSL_VERIFY_PEER一起使用
當(dāng)SSL_VERIFY_PEER被設(shè)置時(shí)verify_callback可以控制驗(yàn)證的行為。任何一個(gè)驗(yàn)證失敗信息都會(huì)終止TLS連接
static int s_server_verify=SSL_VERIFY_NONE;
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL/*verify_callback*/);
為了從自己本身的程序中產(chǎn)生一個(gè)session_id,所以要給本程序設(shè)定一個(gè)session_id_context,否則程序從外部獲取session_id_context來得到session_id,那很容易產(chǎn)生錯(cuò)誤
長度不能大于SSL_MAX_SSL_SESSION_ID_LENGTH
const unsigned char s_server_session_id_context[100]="1111asdfd";
SSL_CTX_set_session_id_context(ctx,s_server_session_id_context,sizeof s_server_session_id_context);
return ctx;