📄 s3_srvr.c
字号:
buf=(unsigned char *)s->init_buf->data; p=s->s3->server_random; Time=(unsigned long)time(NULL); /* Time */ l2n(Time,p); if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) return -1; /* Do the message type and length last */ d=p= &(buf[4]); *(p++)=s->version>>8; *(p++)=s->version&0xff; /* Random stuff */ memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; /* now in theory we have 3 options to sending back the * session id. If it is a re-use, we send back the * old session-id, if it is a new session, we send * back the new session-id or we send back a 0 length * session-id if we want it to be single use. * Currently I will not implement the '0' length session-id * 12-Jan-98 - I'll now support the '0' length stuff. */ if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) s->session->session_id_length=0; sl=s->session->session_id_length; if (sl > (int)sizeof(s->session->session_id)) { SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); return -1; } *(p++)=sl; memcpy(p,s->session->session_id,sl); p+=sl; /* put the cipher */ i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p); p+=i; /* put the compression method */#ifdef OPENSSL_NO_COMP *(p++)=0;#else if (s->s3->tmp.new_compression == NULL) *(p++)=0; else *(p++)=s->s3->tmp.new_compression->id;#endif /* do the header */ l=(p-d); d=buf; *(d++)=SSL3_MT_SERVER_HELLO; l2n3(l,d); s->state=SSL3_ST_CW_CLNT_HELLO_B; /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; } /* SSL3_ST_CW_CLNT_HELLO_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); }int ssl3_send_server_done(SSL *s) { unsigned char *p; if (s->state == SSL3_ST_SW_SRVR_DONE_A) { p=(unsigned char *)s->init_buf->data; /* do the header */ *(p++)=SSL3_MT_SERVER_DONE; *(p++)=0; *(p++)=0; *(p++)=0; s->state=SSL3_ST_SW_SRVR_DONE_B; /* number of bytes to write */ s->init_num=4; s->init_off=0; } /* SSL3_ST_CW_CLNT_HELLO_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); }int ssl3_send_server_key_exchange(SSL *s) {#ifndef OPENSSL_NO_RSA unsigned char *q; int j,num; RSA *rsa; unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; unsigned int u;#endif#ifndef OPENSSL_NO_DH DH *dh=NULL,*dhp;#endif#ifndef OPENSSL_NO_ECDH EC_KEY *ecdh=NULL, *ecdhp; unsigned char *encodedPoint = NULL; int encodedlen = 0; int curve_id = 0; BN_CTX *bn_ctx = NULL; #endif EVP_PKEY *pkey; unsigned char *p,*d; int al,i; unsigned long type; int n; CERT *cert; BIGNUM *r[4]; int nr[4],kn; BUF_MEM *buf; EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); if (s->state == SSL3_ST_SW_KEY_EXCH_A) { type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; cert=s->cert; buf=s->init_buf; r[0]=r[1]=r[2]=r[3]=NULL; n=0;#ifndef OPENSSL_NO_RSA if (type & SSL_kRSA) { rsa=cert->rsa_tmp; if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { rsa=s->cert->rsa_tmp_cb(s, SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); if(rsa == NULL) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY); goto f_err; } RSA_up_ref(rsa); cert->rsa_tmp=rsa; } if (rsa == NULL) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY); goto f_err; } r[0]=rsa->n; r[1]=rsa->e; s->s3->tmp.use_rsa_tmp=1; } else#endif#ifndef OPENSSL_NO_DH if (type & SSL_kEDH) { dhp=cert->dh_tmp; if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) dhp=s->cert->dh_tmp_cb(s, SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); if (dhp == NULL) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); goto f_err; } if (s->s3->tmp.dh != NULL) { DH_free(dh); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } if ((dh=DHparams_dup(dhp)) == NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; } s->s3->tmp.dh=dh; if ((dhp->pub_key == NULL || dhp->priv_key == NULL || (s->options & SSL_OP_SINGLE_DH_USE))) { if(!DH_generate_key(dh)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); goto err; } } else { dh->pub_key=BN_dup(dhp->pub_key); dh->priv_key=BN_dup(dhp->priv_key); if ((dh->pub_key == NULL) || (dh->priv_key == NULL)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; } } r[0]=dh->p; r[1]=dh->g; r[2]=dh->pub_key; } else #endif#ifndef OPENSSL_NO_ECDH if (type & SSL_kECDHE) { const EC_GROUP *group; ecdhp=cert->ecdh_tmp; if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) { ecdhp=s->cert->ecdh_tmp_cb(s, SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); } if (ecdhp == NULL) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY); goto f_err; } if (s->s3->tmp.ecdh != NULL) { EC_KEY_free(s->s3->tmp.ecdh); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } /* Duplicate the ECDH structure. */ if (ecdhp == NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } if (!EC_KEY_up_ref(ecdhp)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } ecdh = ecdhp; s->s3->tmp.ecdh=ecdh; if ((EC_KEY_get0_public_key(ecdh) == NULL) || (EC_KEY_get0_private_key(ecdh) == NULL) || (s->options & SSL_OP_SINGLE_ECDH_USE)) { if(!EC_KEY_generate_key(ecdh)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } } if (((group = EC_KEY_get0_group(ecdh)) == NULL) || (EC_KEY_get0_public_key(ecdh) == NULL) || (EC_KEY_get0_private_key(ecdh) == NULL)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && (EC_GROUP_get_degree(group) > 163)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); goto err; } /* XXX: For now, we only support ephemeral ECDH * keys over named (not generic) curves. For * supported named curves, curve_id is non-zero. */ if ((curve_id = nid2curve_id(EC_GROUP_get_curve_name(group))) == 0) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); goto err; } /* Encode the public key. * First check the size of encoding and * allocate memory accordingly. */ encodedlen = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); encodedPoint = (unsigned char *) OPENSSL_malloc(encodedlen*sizeof(unsigned char)); bn_ctx = BN_CTX_new(); if ((encodedPoint == NULL) || (bn_ctx == NULL)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); goto err; } encodedlen = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encodedlen, bn_ctx); if (encodedlen == 0) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } BN_CTX_free(bn_ctx); bn_ctx=NULL; /* XXX: For now, we only support named (not * generic) curves in ECDH ephemeral key exchanges. * In this situation, we need three additional bytes * to encode the entire ServerECDHParams * structure. */ n = 3 + encodedlen; /* We'll generate the serverKeyExchange message * explicitly so we can set these to NULLs */ r[0]=NULL; r[1]=NULL; r[2]=NULL; } else #endif /* !OPENSSL_NO_ECDH */ { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } for (i=0; r[i] != NULL; i++) { nr[i]=BN_num_bytes(r[i]); n+=2+nr[i]; } if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) { if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) == NULL) { al=SSL_AD_DECODE_ERROR; goto f_err; } kn=EVP_PKEY_size(pkey); } else { pkey=NULL; kn=0; } if (!BUF_MEM_grow_clean(buf,n+4+kn)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF); goto err; } d=(unsigned char *)s->init_buf->data; p= &(d[4]); for (i=0; r[i] != NULL; i++) { s2n(nr[i],p); BN_bn2bin(r[i],p); p+=nr[i]; }#ifndef OPENSSL_NO_ECDH if (type & SSL_kECDHE) { /* XXX: For now, we only support named (not generic) curves. * In this situation, the serverKeyExchange message has: * [1 byte CurveType], [1 byte CurveName] * [1 byte length of encoded point], followed by * the actual encoded point itself */ *p = NAMED_CURVE_TYPE; p += 1; *p = curve_id; p += 1; *p = encodedlen; p += 1; memcpy((unsigned char*)p, (unsigned char *)encodedPoint, encodedlen); OPENSSL_free(encodedPoint); p += encodedlen; }#endif /* not anonymous */ if (pkey != NULL) { /* n is the length of the params, they start at &(d[4]) * and p points to the space at the end. */#ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { q=md_buf; j=0; for (num=2; num > 0; num--) { EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md_ctx,&(d[4]),n); EVP_DigestFinal_ex(&md_ctx,q, (unsigned int *)&i); q+=i; j+=i; } if (RSA_sign(NID_md5_sha1, md_buf, j, &(p[2]), &u, pkey->pkey.rsa) <= 0) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA); goto err; } s2n(u,p); n+=u+2; } else#endif#if !defined(OPENSSL_NO_DSA) if (pkey->type == EVP_PKEY_DSA) { /* lets do DSS */ EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL); EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); EVP_SignUpdate(&md_ctx,&(d[4]),n); if (!EVP_SignFinal(&md_ctx,&(p[2]), (unsigned int *)&i,pkey)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA); goto err; } s2n(i,p); n+=i+2; } else#endif#if !defined(OPENSSL_NO_ECDSA) if (pkey->type == EVP_PKEY_EC) { /* let's do ECDSA */ EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL); EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); EVP_SignUpdate(&md_ctx,&(d[4]),n); if (!EVP_SignFinal(&md_ctx,&(p[2]), (unsigned int *)&i,pkey)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA); goto err; } s2n(i,p); n+=i+2; } else#endif { /* Is this error check actually needed? */ al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE); goto f_err; } } *(d++)=SSL3_MT_SERVER_KEY_EXCHANGE; l2n3(n,d); /* we should now have things packed up, so lets send * it off */ s->init_num=n+4; s->init_off=0; } s->state = SSL3_ST_SW_KEY_EXCH_B; EVP_MD_CTX_cleanup(&md_ctx); return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al);err:#ifndef OPENSSL_NO_ECDH if (encodedPoint != NULL) OPENSSL_free(encodedPoint); BN_CTX_free(bn_ctx);#endif EVP_MD_CTX_cleanup(&md_ctx); return(-1); }int ssl3_send_certificate_request(SSL *s) { unsigned char *p,*d; int i,j,nl,off,n; STACK_OF(X509_NAME) *sk=NULL; X509_NAME *name; BUF_MEM *buf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -