📄 s2_srvr.c
字号:
{ if (p[-1] != SSL2_MT_ERROR) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE); } else SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR); return(-1); } cp=ssl2_get_cipher_by_char(p); if (cp == NULL) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); return(-1); } s->session->cipher= cp; p+=3; n2s(p,i); s->s2->tmp.clear=i; n2s(p,i); s->s2->tmp.enc=i; n2s(p,i); s->session->key_arg_length=i; if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); return -1; } s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B; } /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */ p=(unsigned char *)s->init_buf->data; if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } keya=s->session->key_arg_length; len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya; if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG); return -1; } n = (int)len - s->init_num; i = ssl2_read(s,(char *)&(p[s->init_num]),n); if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i)); if (s->msg_callback) s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */ p += 10; memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]), (unsigned int)keya); if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY); return(-1); } i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc, &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]), (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); is_export=SSL_C_IS_EXPORT(s->session->cipher); if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); return(0); } if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) { is_export=1; ek=8; } else ek=5; /* bad decrypt */#if 1 /* If a bad decrypt, continue with protocol but with a * random master secret (Bleichenbacher attack) */ if ((i < 0) || ((!is_export && (i != EVP_CIPHER_key_length(c))) || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i != (unsigned int)EVP_CIPHER_key_length(c)))))) { ERR_clear_error(); if (is_export) i=ek; else i=EVP_CIPHER_key_length(c); if (RAND_pseudo_bytes(p,i) <= 0) return 0; }#else if (i < 0) { error=1; SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT); } /* incorrect number of key bytes for non export cipher */ else if ((!is_export && (i != EVP_CIPHER_key_length(c))) || (is_export && ((i != ek) || (s->s2->tmp.clear+i != EVP_CIPHER_key_length(c))))) { error=1; SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS); } if (error) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); }#endif if (is_export) i+=s->s2->tmp.clear; if (i > SSL_MAX_MASTER_KEY_LENGTH) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } s->session->master_key_length=i; memcpy(s->session->master_key,p,(unsigned int)i); return(1); }static int get_client_hello(SSL *s) { int i,n; unsigned long len; unsigned char *p; STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */ STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */ STACK_OF(SSL_CIPHER) *prio, *allow; int z; /* This is a bit of a hack to check for the correct packet * type the first time round. */ if (s->state == SSL2_ST_GET_CLIENT_HELLO_A) { s->first_packet=1; s->state=SSL2_ST_GET_CLIENT_HELLO_B; } p=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_GET_CLIENT_HELLO_B) { i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num); if (i < (9-s->init_num)) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i)); s->init_num = 9; if (*(p++) != SSL2_MT_CLIENT_HELLO) { if (p[-1] != SSL2_MT_ERROR) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE); } else SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR); return(-1); } n2s(p,i); if (i < s->version) s->version=i; n2s(p,i); s->s2->tmp.cipher_spec_length=i; n2s(p,i); s->s2->tmp.session_id_length=i; n2s(p,i); s->s2->challenge_length=i; if ( (i < SSL2_MIN_CHALLENGE_LENGTH) || (i > SSL2_MAX_CHALLENGE_LENGTH)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH); return(-1); } s->state=SSL2_ST_GET_CLIENT_HELLO_C; } /* SSL2_ST_GET_CLIENT_HELLO_C */ p=(unsigned char *)s->init_buf->data; len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length; if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG); return -1; } n = (int)len - s->init_num; i = ssl2_read(s,(char *)&(p[s->init_num]),n); if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i)); if (s->msg_callback) s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */ p += 9; /* get session-id before cipher stuff so we can get out session * structure if it is cached */ /* session-id */ if ((s->s2->tmp.session_id_length != 0) && (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH); return(-1); } if (s->s2->tmp.session_id_length == 0) { if (!ssl_get_new_session(s,1)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } } else { i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]), s->s2->tmp.session_id_length); if (i == 1) { /* previous session */ s->hit=1; } else if (i == -1) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } else { if (s->cert == NULL) { ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE); SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET); return(-1); } if (!ssl_get_new_session(s,1)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } } } if (!s->hit) { cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length, &s->session->ciphers); if (cs == NULL) goto mem_err; cl=SSL_get_ciphers(s); if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { prio=sk_SSL_CIPHER_dup(cl); if (prio == NULL) goto mem_err; allow = cs; } else { prio = cs; allow = cl; } for (z=0; z<sk_SSL_CIPHER_num(prio); z++) { if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0) { sk_SSL_CIPHER_delete(prio,z); z--; } } if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { sk_SSL_CIPHER_free(s->session->ciphers); s->session->ciphers = prio; } /* s->session->ciphers should now have a list of * ciphers that are on both the client and server. * This list is ordered by the order the client sent * the ciphers or in the order of the server's preference * if SSL_OP_CIPHER_SERVER_PREFERENCE was set. */ } p+=s->s2->tmp.cipher_spec_length; /* done cipher selection */ /* session id extracted already */ p+=s->s2->tmp.session_id_length; /* challenge */ if (s->s2->challenge_length > sizeof s->s2->challenge) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); return -1; } memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length); return(1);mem_err: SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE); return(0); }static int server_hello(SSL *s) { unsigned char *p,*d; int n,hit; STACK_OF(SSL_CIPHER) *sk; p=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_SEND_SERVER_HELLO_A) { d=p+11; *(p++)=SSL2_MT_SERVER_HELLO; /* type */ hit=s->hit; *(p++)=(unsigned char)hit;#if 1 if (!hit) { if (s->session->sess_cert != NULL) /* This can't really happen because get_client_hello * has called ssl_get_new_session, which does not set * sess_cert. */ ssl_sess_cert_free(s->session->sess_cert); s->session->sess_cert = ssl_sess_cert_new(); if (s->session->sess_cert == NULL) { SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE); return(-1); } } /* If 'hit' is set, then s->sess_cert may be non-NULL or NULL, * depending on whether it survived in the internal cache * or was retrieved from an external cache. * If it is NULL, we cannot put any useful data in it anyway, * so we don't touch it. */#else /* That's what used to be done when cert_st and sess_cert_st were * the same. */ if (!hit) { /* else add cert to session */ CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT); if (s->session->sess_cert != NULL) ssl_cert_free(s->session->sess_cert); s->session->sess_cert=s->cert; } else /* We have a session id-cache hit, if the * session-id has no certificate listed against * the 'cert' structure, grab the 'old' one * listed against the SSL connection */ { if (s->session->sess_cert == NULL) { CRYPTO_add(&s->cert->references,1, CRYPTO_LOCK_SSL_CERT); s->session->sess_cert=s->cert; } }#endif if (s->cert == NULL) { ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE); SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED); return(-1); } if (hit) { *(p++)=0; /* no certificate type */ s2n(s->version,p); /* version */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -