解决方案

SSL连接建立过程分析(1)

seo靠我 2023-09-24 16:54:49

Https协议:SSL建立过程分析

web訪问的两种方式:

http协议,我们普通情况下是通过它訪问web,由于它不要求太多的安全机制,使用起来也简单,非常多web网站也仅仅支持这样的方式下的訪问.

httSEO靠我ps协议(Hypertext Transfer Protocol over Secure Socket Layer),对于安全性要求比較高的情况,能够通过它訪问web,比方工商银行https://wwSEO靠我w.icbc.com.cn/icbc/(当然也能够通过http协议訪问,仅仅是没那么安全了).其安全基础是SSL协议.

SSL协议,当前版本号为3.1(SSL3.1就是TLS1.0)。它已被广泛地用于WSEO靠我eb浏览器与server之间的身份认证和加密传输数据.它位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record ProtocolSEO靠我):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际SEO靠我的传输数据開始前,通讯两方进行身份认证、协商加密算法、交换加密密钥等。

为了了解具体过程,能够通过网络抓包工具(Commview,Iris)分析https协议,SSL连接建立过程中,数据包交换情况.

数据SEO靠我包分析过程用到的几个图.

图,SSL Protocol Stack

图.SSL Record Format

图.SSL Record Protocol Payload

图.Handshake ProtocolSEO靠我 Action

它们来之.Cryptography and Network Security Principles and Practices, Fourth Edition-Chapter 17. WSEO靠我eb Security-17.2. Secure Socket Layer and Transport Layer Security(password学与网络安全 原理与实践第四版,17章web安全,SEO靠我17.2节,SSL与TLS)详细细节參考本书.

以下跟踪握手过程(图Handshake Protocol Action)中,数据包的交换.

以为https方式訪问www.sun.com为样例,一般大型公司SEO靠我,银行的web都支持https訪问,如工商银行,sun,微软,IBM.

在IE中输入:https://wwww.sun.com,由于这是https协议,所以在实际訪问web前,会建立SSL连接.

通过CoSEO靠我mmview抓包工具,过滤443port(普通情况下,HTTPS使用port443,HTTP使用port80)能够得到数据包.

数据包大致情况和(图Handshake Protocol Action)SEO靠我.

SSL连接建立过程分析(1)

1. 应用程序接口 1.1 SSL初始化 SSL_CTX* InitSSL(int server, char *cert, char *key, char *pw)

{

SSEO靠我SL_CTX* ctx;

    SSL_METHOD *meth;

    int status; // 算法初始化  

// 载入SSL错误信息

    SSL_load_error_strings();

// 加入�SSL的加密/HSEO靠我ASH算法

    SSLeay_add_ssl_algorithms();

// 服务器还是客户端

    If(server)

 meth = SSLv23_server_method();

    else

meth = SSLv2SEO靠我3_client_method();

// 建立新的SSL上下文

    ctx = SSL_CTX_new (meth);

    if(!ctx) return NULL; // 设置证书文件的口令

SSL_CTX_seSEO靠我t_default_passwd_cb_userdata(ctx, pw);

//载入本地证书文件

status=SSL_CTX_use_certificate_file(ctx, cert, SSL_FSEO靠我ILETYPE_ASN1);

    if (status <= 0) {

        frintf(stderr, "Use cert fail, status=%d/n", status);

        goto bad;

    }

// 载入SEO靠我私钥文件

    if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0) {

fprintf(stderr, "Use private SEO靠我key fail/n");

        goto bad;

    }

// 检查证书和私钥是否匹配

    if (!SSL_CTX_check_private_key(ctx)) {

fprintf("Private key doesSEO靠我 not match the certificate public key/n");

        goto bad;

    }

    fprintf("Cert and key OK/n");

    return ctx;

bad:

SSL_SEO靠我CTX_free (ctx);

    return NULL;

} 1.2 建立SSL新连接 server: // 建立SSL

ssl = SSL_new (ctx);

// 将SSL与TCP socket连接

SSSEO靠我L_set_fd (ssl, sd);

//接受新SSL连接

err = SSL_accept (ssl); client:

// 建立SSL

ssl = SSL_new (ctx);

// 将SSL与TCP SEO靠我socket连接

SSL_set_fd (ssl, sd);

// SSL连接

err = SSL_connect (ssl);

server的SSL_accept()和client的SSL_connect(SEO靠我)函数共同完毕SSL的握手协商过程。 1.3 SSL通信 和普通的read()/write()调用一样,用以下的函数完毕数据的SSL发送和接收,函数输入数据是明文,SSL自己主动将数据封装进SSL中:SEO靠我 读/接收:SSL_read()

写/发送:SSL_write() 1.4 SSL释放 SSL释放非常easy: SSL_free (ssl); 2. SSL实现分析 下面SSL源码取自openssl-SEO靠我0.9.7b。

2.1 SSL_load_error_strings 该函数载入错误字符串信息: void SSL_load_error_strings(void)

 {

#ifndef OPENSSL_NOSEO靠我_ERR

 ERR_load_crypto_strings();

 ERR_load_SSL_strings();

#endif

} 最后将会进入函数: static void err_load_strings(SEO靠我int lib, ERR_STRING_DATA *str)

 {

 while (str->error)

  {

  str->error|=ERR_PACK(lib,0,0);

ERRFN(err_set_item)(SEO靠我str);

  str++;

  }

 }

当中:

#define ERR_PACK(l,f,r)  (((((unsigned long)l)&0xffL)*0x1000000)| /

((((unsigned longSEO靠我)f)&0xfffL)*0x1000)| /

((((unsigned long)r)&0xfffL))) #define ERRFN(a) err_fns->cb_##a ERRFN(err_set_SEO靠我item)(str)的实际函数实现为: static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)

 {

ERR_STRING_DATA *p;SEO靠我

 LHASH *hash; err_fns_check();

 hash = ERRFN(err_get)(1);

 if (!hash)

return NULL; CRYPTO_w_lock(CRYPTO_LOSEO靠我CK_ERR);

 p = (ERR_STRING_DATA *)lh_insert(hash, d);

 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); return p;

} Lh_inSEO靠我sert()将错误信息插入到一个链表中 如关于加密算法的错误信息: /* crypto/err/err.c */

static ERR_STRING_DATA ERR_str_functs[]=

……

stSEO靠我atic ERR_STRING_DATA ERR_str_libraries[]=

……

static ERR_STRING_DATA ERR_str_reasons[]=

…… 2.2 SSLeay_adSEO靠我d_ssl_algorithms() 这实际是个宏:

#define OpenSSL_add_ssl_algorithms()    SSL_library_init()

#define SSLeay_aSEO靠我dd_ssl_algorithms() SSL_library_init() 实际函数为SSL_library_init(),函数比較简单,就是载入各种加密和HASH算法: /* ssl/ssl_alSEO靠我gs.c */

int SSL_library_init(void)

 { #ifndef OPENSSL_NO_DES

 EVP_add_cipher(EVP_des_cbc());

EVP_add_cipheSEO靠我r(EVP_des_ede3_cbc());

#endif

#ifndef OPENSSL_NO_IDEA

 EVP_add_cipher(EVP_idea_cbc());

#endif

#ifndef OPENSEO靠我SSL_NO_RC4

 EVP_add_cipher(EVP_rc4());

#endif 

#ifndef OPENSSL_NO_RC2

 EVP_add_cipher(EVP_rc2_cbc());

#endifSEO靠我

#ifndef OPENSSL_NO_AES

 EVP_add_cipher(EVP_aes_128_cbc());

 EVP_add_cipher(EVP_aes_192_cbc());

EVP_add_ciSEO靠我pher(EVP_aes_256_cbc());

#endif

#ifndef OPENSSL_NO_MD2

 EVP_add_digest(EVP_md2());

#endif

#ifndef OPENSSL_SEO靠我NO_MD5

 EVP_add_digest(EVP_md5());

 EVP_add_digest_alias(SN_md5,"ssl2-md5");

EVP_add_digest_alias(SN_md5,SEO靠我"ssl3-md5");

#endif

#ifndef OPENSSL_NO_SHA

 EVP_add_digest(EVP_sha1()); /* RSA with sha1 */

EVP_add_digesSEO靠我t_alias(SN_sha1,"ssl3-sha1");

 EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);

#endif

#ifSEO靠我 !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)

EVP_add_digest(EVP_dss1()); /* DSA with sha1 */SEO靠我

 EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);

 EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");

EVSEO靠我P_add_digest_alias(SN_dsaWithSHA1,"dss1");

#endif

/* If you want support for phased out ciphers, add tSEO靠我he following */

#if 0

 EVP_add_digest(EVP_sha());

 EVP_add_digest(EVP_dss());

#endif

 return(1);

 }

2.3 SSL23_sSEO靠我erver_method() 建立服务器端的方法库,这是个通用函数,可动态选择SSL协议。假设想固定协议,能够仅仅用SSLv2_server_method(), SSLv3_server_methodSEO靠我() 等函数来初始化,该函数返回一个SSL_METHOD结构: /* ssl/ssl.h */

/* Used to hold functions for SSLv2 or SSLv3/TLSv1 fuSEO靠我nctions */

typedef struct ssl_method_st

 {

 int version; // 版本号号

 int (*ssl_new)(SSL *s); // 建立新SSL

void (*sSEO靠我sl_clear)(SSL *s); // 清除SSL

 void (*ssl_free)(SSL *s);  // 释放SSL

int (*ssl_accept)(SSL *s); // server接受SEO靠我SSL连接

 int (*ssl_connect)(SSL *s); // client的SSL连接

 int (*ssl_read)(SSL *s,void *buf,int len); // SSL读

inSEO靠我t (*ssl_peek)(SSL *s,void *buf,int len); // SSL查看数据

int (*ssl_write)(SSL *s,const void *buf,int len);SEO靠我 // SSL写

 int (*ssl_shutdown)(SSL *s); // SSL半关闭

 int (*ssl_renegotiate)(SSL *s); // SSL重协商

int (*ssl_renSEO靠我egotiate_check)(SSL *s); // SSL重协商检查

 long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg); // SSL控制

lSEO靠我ong (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg); //SSL上下文控制

SSL_CIPHER *(*get_cipher_bSEO靠我y_char)(const unsigned char *ptr); // 通过名称获取SSL的算法

int (*put_cipher_by_char)(const SSL_CIPHER *cipherSEO靠我,unsigned char *ptr);

 int (*ssl_pending)(SSL *s);

 int (*num_ciphers)(void); // 算法数

SSL_CIPHER *(*get_ciSEO靠我pher)(unsigned ncipher); // 获取算法

 struct ssl_method_st *(*get_ssl_method)(int version);

long (*get_timeSEO靠我out)(void); // 超时

 struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ // SSL3加密

int (*ssl_veSEO靠我rsion)(); // SSL版本号

 long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)()); // SSL控制回调函数

long (*ssSEO靠我l_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)()); //SSL上下文控制回调函数

 } SSL_METHOD;

/* ssl/s23_srvSEO靠我r.c */ SSL_METHOD *SSLv23_server_method(void)

 {

 static int init=1;

// 静态量,每一个进程仅仅初始化一次

static SSL_METHODSEO靠我 SSLv23_server_data; if (init)

  {

  CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); if (init)

   {

// ssl23的基本方法结构

memcpSEO靠我y((char *)&SSLv23_server_data,

    (char *)sslv23_base_method(),sizeof(SSL_METHOD));

// 服务器,所以要定义accept方法

SSEO靠我SLv23_server_data.ssl_accept=ssl23_accept;

// 依据SSL的版本号设置SSL的详细方法函数

SSLv23_server_data.get_ssl_method=SEO靠我ssl23_get_server_method;

   init=0;

   } CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);

  }

return(&SSLv23_server_dataSEO靠我);

 }

static SSL_METHOD *ssl23_get_server_method(int ver)

 {

#ifndef OPENSSL_NO_SSL2

if (ver == SSL2_VERSIOSEO靠我N)

  return(SSLv2_server_method());

#endif

 if (ver == SSL3_VERSION)

  return(SSLv3_server_method());

else if SEO靠我(ver == TLS1_VERSION)

  return(TLSv1_server_method());

// 随着TLS1.1(RFC4346)的推出,预计不久将出现TLSv1_1_server_metSEO靠我hod()

 else

  return(NULL);

 } // SSL23的方法基本数据定义

/* ssl/s23_lib.c */

SSL_METHOD *sslv23_base_method(void)

 {

retSEO靠我urn(&SSLv23_data);

 } static SSL_METHOD SSLv23_data= {

 TLS1_VERSION,

 tls1_new,

 tls1_clear,

 tls1_free,

ssl_uSEO靠我ndefined_function,

 ssl_undefined_function,

 ssl23_read,

 ssl23_peek,

 ssl23_write,

 ssl_undefined_function,

ssSEO靠我l_undefined_function,

 ssl_ok,

 ssl3_ctrl,

 ssl3_ctx_ctrl,

 ssl23_get_cipher_by_char,

ssl23_put_cipher_by_chaSEO靠我r,

 ssl_undefined_function,

 ssl23_num_ciphers,

 ssl23_get_cipher,

 ssl_bad_method,

 ssl23_default_timeout,

&ssSEO靠我l3_undef_enc_method,

 ssl_undefined_function,

 ssl3_callback_ctrl,

 ssl3_ctx_callback_ctrl,

}; 以SSL3的serverSEO靠我方法函数为例,其它方法相似: /* ssl/s3_srvr.c */ SSL_METHOD *SSLv3_server_method(void)

 {

 static int init=1;

static SSSEO靠我L_METHOD SSLv3_server_data; // 仅仅初始化一次

 if (init)

  {

  CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); if (init)

   {

// SEO靠我ssl3的基本方法结构

   memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),

    sizeof(SSL_METHOD));

// ssl3SEO靠我的接受方法

   SSLv3_server_data.ssl_accept=ssl3_accept;

// ssl3获取服务器的方法函数

SSLv3_server_data.get_ssl_method=ssl3SEO靠我_get_server_method;

   init=0;

   }

  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);

  }

 return(&SSLv3_server_data);

} // SEO靠我SSL3的方法基本数据定义

/* ssl/s3_lib.c */

static SSL_METHOD SSLv3_data= {

 SSL3_VERSION,

 ssl3_new,

 ssl3_clear,

ssl3_SEO靠我free,

 ssl_undefined_function,

 ssl_undefined_function,

 ssl3_read,

 ssl3_peek,

 ssl3_write,

 ssl3_shutdown,

ssl3SEO靠我_renegotiate,

 ssl3_renegotiate_check,

 ssl3_ctrl,

 ssl3_ctx_ctrl,

 ssl3_get_cipher_by_char,

ssl3_put_cipher_SEO靠我by_char,

 ssl3_pending,

 ssl3_num_ciphers,

 ssl3_get_cipher,

 ssl_bad_method,

 ssl3_default_timeout,

&SSLv3_encSEO靠我_data,

 ssl_undefined_function,

 ssl3_callback_ctrl,

 ssl3_ctx_callback_ctrl,

 }; 2.4 SSL23_client_method()

SEO靠我server端的事实上是同样的,仅仅是不定义结构中的ssl_accept而是定义ssl_connnect: SSL_METHOD *SSLv23_client_method(void)

 {

static SEO靠我int init=1;

 static SSL_METHOD SSLv23_client_data; if (init)

  {

CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); ifSEO靠我 (init)

   {

   memcpy((char *)&SSLv23_client_data,

    (char *)sslv23_base_method(),sizeof(SSL_METHOD));

SSLv23_cSEO靠我lient_data.ssl_connect=ssl23_connect;

   SSLv23_client_data.get_ssl_method=ssl23_get_client_method;

init=SEO靠我0;

   } CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);

  }

 return(&SSLv23_client_data);

} 2.5 SSL_CTX_new () 该函数依据SSEO靠我SL方法获取一个SSL上下文结构,该结构定义为: /* ssl/ssl.h */

struct ssl_ctx_st

 {

SSL_METHOD *method; STACK_OF(SSL_CIPHER) *SEO靠我cipher_list;

 /* same as above but sorted for lookup */

STACK_OF(SSL_CIPHER) *cipher_list_by_id; structSEO靠我 x509_store_st /* X509_STORE */ *cert_store;

struct lhash_st /* LHASH */ *sessions; /* a set of SSL_SSEO靠我ESSIONs */

 /* Most session-ids that will be cached, default is

* SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0SEO靠我 is unlimited. */

 unsigned long session_cache_size;

 struct ssl_session_st *session_cache_head;

struct sSEO靠我sl_session_st *session_cache_tail; /* This can have one of 2 values, ored together,

* SSL_SESS_CACHE_SEO靠我CLIENT,

  * SSL_SESS_CACHE_SERVER,

  * Default is SSL_SESSION_CACHE_SERVER, which means only

* SSL_accept wSEO靠我hich cache SSL_SESSIONS. */

int session_cache_mode; /* If timeout is not 0, it is the default timeoutSEO靠我 value set

  * when SSL_new() is called.  This has been put in to make

* life easier to set things up */SEO靠我

 long session_timeout; /* If this callback is not null, it will be called each

* time a session id is SEO靠我added to the cache.  If this function

  * returns 1, it means that the callback will do a

* SSL_SESSION_SEO靠我free() when it has finished using it.  Otherwise,

* on 0, it means the callback has finished with it.SEO靠我

  * If remove_session_cb is not null, it will be called when

* a session-id is removed from the cache. SEO靠我 After the call,

  * OpenSSL will SSL_SESSION_free() it. */

int (*new_session_cb)(struct ssl_st *ssl,SSLSEO靠我_SESSION *sess);

 void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess);

SSL_SESSION *(*gSEO靠我et_session_cb)(struct ssl_st *ssl,

  unsigned char *data,int len,int *copy); struct

  {

int sess_connect; /SEO靠我* SSL new conn - started */

  int sess_connect_renegotiate;/* SSL reneg - requested */

int sess_connect_SEO靠我good; /* SSL new conne/reneg - finished */

  int sess_accept; /* SSL new accept - started */

int sess_acSEO靠我cept_renegotiate;/* SSL reneg - requested */

  int sess_accept_good; /* SSL accept/reneg - finished */

iSEO靠我nt sess_miss;  /* session lookup misses  */

int sess_timeout; /* reuse attempt on timeouted session *SEO靠我/

  int sess_cache_full; /* session removed due to full cache */

int sess_hit;  /* session reuse actuallSEO靠我y done */

  int sess_cb_hit; /* session-id that was not

      * in the cache was

* passed back via the callbackSEO靠我.  This

      * indicates that the application is

      * supplying session-ids from other

* processes - spooky :-)SEO靠我 */

  } stats; int references; /* if defined, these override the X509_verify_cert() calls */

int (*app_vSEO靠我erify_callback)(X509_STORE_CTX *, void *);

 void *app_verify_arg;

/* before OpenSSL 0.9.7, app_verify_aSEO靠我rg was ignored

* (app_verify_callback was called with just one argument) */ /* Default password callbSEO靠我ack. */

 pem_password_cb *default_passwd_callback; /* Default password callback user data. */

void *defSEO靠我ault_passwd_callback_userdata; /* get client cert callback */

int (*client_cert_cb)(SSL *ssl, X509 **SEO靠我x509, EVP_PKEY **pkey); CRYPTO_EX_DATA ex_data; const EVP_MD *rsa_md5;/* For SSLv2 - name is ssl2-mdSEO靠我5 */

 const EVP_MD *md5; /* For SSLv3/TLSv1 ssl3-md5 */

const EVP_MD *sha1;   /* For SSLv3/TLSv1 ssl3->SEO靠我sha1 */ STACK_OF(X509) *extra_certs;

STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSEO靠我Sv1 */

/* Default values used when no per-SSL value is defined follow */ void (*info_callback)(const SEO靠我SSL *ssl,int type,int val); /* used if SSLs info_callback is NULL */ /* what we put in client cert rSEO靠我equests */

 STACK_OF(X509_NAME) *client_CA;

/* Default values to use in SSL structures follow (these arSEO靠我e copied by SSL_new) */ unsigned long options;

 unsigned long mode;

long max_cert_list; struct cert_st SEO靠我/* CERT */ *cert;

int read_ahead; /* callback that allows applications to peek at protocol messages *SEO靠我/

void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *SEO靠我ssl, void *arg);

 void *msg_callback_arg; int verify_mode;

 int verify_depth;

unsigned int sid_ctx_lengthSEO靠我;

 unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];

int (*default_verify_callback)(int ok,X509_STORE_CTX SEO靠我*ctx); /* called verify_callback in the SSL */ /* Default generate session ID callback. */

GEN_SESSIOSEO靠我N_CB generate_session_id; int purpose;  /* Purpose setting */

int trust;  /* Trust setting */ int quiSEO靠我et_shutdown;

 };

typedef struct ssl_ctx_st SSL_CTX; /* ssl/ssl_lib.h */

SSL_CTX *SSL_CTX_new(SSL_METHOD SEO靠我*meth)

 {

 SSL_CTX *ret=NULL;

 if (meth == NULL)

  {

  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);

reSEO靠我turn(NULL);

  } if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)

  {

SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFSEO靠我ICATION_SETUP_PROBLEMS);

  goto err;

  }

// 分配上下文的内存空间

 ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));

if (reSEO靠我t == NULL)

  goto err; memset(ret,0,sizeof(SSL_CTX)); // 初始化上下文的结构參数

ret->method=meth; ret->cert_store=NSEO靠我ULL;

 ret->session_cache_mode=SSL_SESS_CACHE_SERVER;

ret->session_cache_size=SSL_SESSION_CACHE_MAX_SIZESEO靠我_DEFAULT;

 ret->session_cache_head=NULL;

ret->session_cache_tail=NULL; /* We take the system default */SEO靠我

 ret->session_timeout=meth->get_timeout(); ret->new_session_cb=0;

 ret->remove_session_cb=0;

ret->get_seSEO靠我ssion_cb=0;

ret->generate_session_id=0; memset((char *)&ret->stats,0,sizeof(ret->stats)); ret->refereSEO靠我nces=1;

 ret->quiet_shutdown=0; /* ret->cipher=NULL;*/

/* ret->s2->challenge=NULL;

ret->master_key=NULL;SEO靠我

 ret->key_arg=NULL;

 ret->s2->conn_id=NULL; */ ret->info_callback=NULL; ret->app_verify_callback=0;

ret-SEO靠我>app_verify_arg=NULL; ret->max_cert_list=SSL_MAX_CERT_LIST_DEFAULT;

 ret->read_ahead=0;

ret->msg_callbaSEO靠我ck=0;

 ret->msg_callback_arg=NULL;

 ret->verify_mode=SSL_VERIFY_NONE;

ret->verify_depth=-1; /* Dont imposSEO靠我e a limit (but x509_lu.c does) */

 ret->sid_ctx_length=0;

 ret->default_verify_callback=NULL;

if ((ret->cSEO靠我ert=ssl_cert_new()) == NULL)

  goto err; ret->default_passwd_callback=0;

ret->default_passwd_callback_usSEO靠我erdata=NULL;

 ret->client_cert_cb=0; ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),

LHASH_COMP_FSEO靠我N(SSL_SESSION_cmp));

 if (ret->sessions == NULL) goto err;

 ret->cert_store=X509_STORE_new();

if (ret->ceSEO靠我rt_store == NULL) goto err; // 建立加密算法链表

 ssl_create_cipher_list(ret->method,

&ret->cipher_list,&ret->ciSEO靠我pher_list_by_id,

  SSL_DEFAULT_CIPHER_LIST);

 if (ret->cipher_list == NULL

|| sk_SSL_CIPHER_num(ret->cipheSEO靠我r_list) <= 0)

  {

  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_LIBRARY_HAS_NO_CIPHERS);

  goto err2;

  } // 定义上下文结构中HASH算法

ifSEO靠我 ((ret->rsa_md5=EVP_get_digestbyname("ssl2-md5")) == NULL)

  {

SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_SEO靠我LOAD_SSL2_MD5_ROUTINES);

  goto err2;

  }

 if ((ret->md5=EVP_get_digestbyname("ssl3-md5")) == NULL)

  {

SSLerr(SSEO靠我SL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);

  goto err2;

  }

if ((ret->sha1=EVP_get_digestbynSEO靠我ame("ssl3-sha1")) == NULL)

  {

  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);

goto erSEO靠我r2;

  } if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL)

goto err; CRYPTO_new_ex_data(CRYPTO_EX_INDSEO靠我EX_SSL_CTX, ret, &ret->ex_data); ret->extra_certs=NULL;

// 压缩算法 ret->comp_methods=SSL_COMP_get_compreSEO靠我ssion_methods(); return(ret);

err:

 SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);

err2:

if (ret != NULLSEO靠我) SSL_CTX_free(ret);

 return(NULL);

 }

...待续...
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2