X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fd1_srvr.c;h=d3afec993db3a7a59eff53556682c1c4d962b943;hp=89f47ce97fb095822a1873a26b1e15ca399992ea;hb=2927791d77ddaef687e92b1779e0bff89bdc279f;hpb=c526ed410cdff6af4729e6abba658759ed19f753 diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 89f47ce97f..d3afec993d 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -133,14 +133,32 @@ static const SSL_METHOD *dtls1_get_server_method(int ver) { if (ver == DTLS1_VERSION) return(DTLSv1_server_method()); + else if (ver == DTLS1_2_VERSION) + return(DTLSv1_2_server_method()); else return(NULL); } -IMPLEMENT_dtls1_meth_func(DTLSv1_server_method, +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, + DTLSv1_server_method, dtls1_accept, ssl_undefined_function, - dtls1_get_server_method) + dtls1_get_server_method, + DTLSv1_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, + DTLSv1_2_server_method, + dtls1_accept, + ssl_undefined_function, + dtls1_get_server_method, + DTLSv1_2_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, + DTLS_server_method, + dtls1_accept, + ssl_undefined_function, + dtls1_get_server_method, + DTLSv1_2_enc_data) int dtls1_accept(SSL *s) { @@ -276,10 +294,11 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_HELLO_REQ_B: s->shutdown=0; + dtls1_clear_record_buffer(s); dtls1_start_timer(s); - ret=dtls1_send_hello_request(s); + ret=ssl3_send_hello_request(s); if (ret <= 0) goto end; - s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C; + s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; s->state=SSL3_ST_SW_FLUSH; s->init_num=0; @@ -382,7 +401,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_SRVR_HELLO_B: s->renegotiate = 2; dtls1_start_timer(s); - ret=dtls1_send_server_hello(s); + ret=ssl3_send_server_hello(s); if (ret <= 0) goto end; if (s->hit) @@ -422,7 +441,7 @@ int dtls1_accept(SSL *s) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { dtls1_start_timer(s); - ret=dtls1_send_server_certificate(s); + ret=ssl3_send_server_certificate(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT if (s->tlsext_status_expected) @@ -484,7 +503,7 @@ int dtls1_accept(SSL *s) ) { dtls1_start_timer(s); - ret=dtls1_send_server_key_exchange(s); + ret=ssl3_send_server_key_exchange(s); if (ret <= 0) goto end; } else @@ -531,7 +550,7 @@ int dtls1_accept(SSL *s) { s->s3->tmp.cert_request=1; dtls1_start_timer(s); - ret=dtls1_send_certificate_request(s); + ret=ssl3_send_certificate_request(s); if (ret <= 0) goto end; #ifndef NETSCAPE_HANG_BUG s->state=SSL3_ST_SW_SRVR_DONE_A; @@ -560,7 +579,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_SRVR_DONE_A: case SSL3_ST_SW_SRVR_DONE_B: dtls1_start_timer(s); - ret=dtls1_send_server_done(s); + ret=ssl3_send_server_done(s); if (ret <= 0) goto end; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; s->state=SSL3_ST_SW_FLUSH; @@ -591,15 +610,16 @@ int dtls1_accept(SSL *s) ret = ssl3_check_client_hello(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); if (ret == 2) + { + dtls1_stop_timer(s); s->state = SSL3_ST_SR_CLNT_HELLO_C; + } else { /* could be sent for a DH cert, even if we * have not asked for it :-) */ ret=ssl3_get_client_certificate(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); s->init_num=0; s->state=SSL3_ST_SR_KEY_EXCH_A; } @@ -609,7 +629,6 @@ int dtls1_accept(SSL *s) case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); #ifndef OPENSSL_NO_SCTP /* Add new shared key for SCTP-Auth, * will be ignored if no SCTP used. @@ -638,6 +657,24 @@ int dtls1_accept(SSL *s) s->state=SSL3_ST_SR_FINISHED_A; s->init_num = 0; } + else if (SSL_USE_SIGALGS(s)) + { + s->state=SSL3_ST_SR_CERT_VRFY_A; + s->init_num=0; + if (!s->session->peer) + break; + /* For sigalgs freeze the handshake buffer + * at this point and digest cached records. + */ + if (!s->s3->handshake_buffer) + { + SSLerr(SSL_F_DTLS1_ACCEPT,ERR_R_INTERNAL_ERROR); + return -1; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) + return -1; + } else { s->state=SSL3_ST_SR_CERT_VRFY_A; @@ -661,7 +698,6 @@ int dtls1_accept(SSL *s) /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && state == SSL_ST_RENEGOTIATE) @@ -693,7 +729,7 @@ int dtls1_accept(SSL *s) #ifndef OPENSSL_NO_TLSEXT case SSL3_ST_SW_SESSION_TICKET_A: case SSL3_ST_SW_SESSION_TICKET_B: - ret=dtls1_send_newsession_ticket(s); + ret=ssl3_send_newsession_ticket(s); if (ret <= 0) goto end; s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; @@ -743,7 +779,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_FINISHED_A: case SSL3_ST_SW_FINISHED_B: - ret=dtls1_send_finished(s, + ret=ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B, s->method->ssl3_enc->server_finished_label, s->method->ssl3_enc->server_finished_label_len); @@ -846,28 +882,6 @@ end: return(ret); } -int dtls1_send_hello_request(SSL *s) - { - unsigned char *p; - - if (s->state == SSL3_ST_SW_HELLO_REQ_A) - { - p=(unsigned char *)s->init_buf->data; - p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0); - - s->state=SSL3_ST_SW_HELLO_REQ_B; - /* number of bytes to write */ - s->init_num=DTLS1_HM_HEADER_LENGTH; - s->init_off=0; - - /* no need to buffer this message, since there are no retransmit - * requests for it */ - } - - /* SSL3_ST_SW_HELLO_REQ_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - int dtls1_send_hello_verify_request(SSL *s) { unsigned int msg_len; @@ -878,8 +892,9 @@ int dtls1_send_hello_verify_request(SSL *s) buf = (unsigned char *)s->init_buf->data; msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); - *(p++) = s->version >> 8; - *(p++) = s->version & 0xFF; + /* Always use DTLS 1.0 version: see RFC 6347 */ + *(p++) = DTLS1_VERSION >> 8; + *(p++) = DTLS1_VERSION & 0xFF; if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, s->d1->cookie, @@ -906,807 +921,3 @@ int dtls1_send_hello_verify_request(SSL *s) /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); } - -int dtls1_send_server_hello(SSL *s) - { - unsigned char *buf; - unsigned char *p,*d; - int i; - unsigned int sl; - unsigned long l,Time; - - if (s->state == SSL3_ST_SW_SRVR_HELLO_A) - { - buf=(unsigned char *)s->init_buf->data; - p=s->s3->server_random; - Time=(unsigned long)time(NULL); /* Time */ - l2n(Time,p); - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); - /* Do the message type and length last */ - d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); - - *(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 > sizeof s->session->session_id) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } - *(p++)=sl; - memcpy(p,s->session->session_id,sl); - p+=sl; - - /* put the cipher */ - if (s->s3->tmp.new_cipher == NULL) - return -1; - 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 - -#ifndef OPENSSL_NO_TLSEXT - if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); - return -1; - } -#endif - - /* do the header */ - l=(p-d); - d=buf; - - d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l); - - s->state=SSL3_ST_SW_SRVR_HELLO_B; - /* number of bytes to write */ - s->init_num=p-buf; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_SW_SRVR_HELLO_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - -int dtls1_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 = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0); - - s->state=SSL3_ST_SW_SRVR_DONE_B; - /* number of bytes to write */ - s->init_num=DTLS1_HM_HEADER_LENGTH; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_SW_SRVR_DONE_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - -int dtls1_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->algorithm_mkey; - 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_DTLS1_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_DTLS1_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_DTLS1_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_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - if ((dh=DHparams_dup(dhp)) == NULL) - { - SSLerr(SSL_F_DTLS1_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_DTLS1_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_DTLS1_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_kEECDH) - { - 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_DTLS1_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_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* Duplicate the ECDH structure. */ - if (ecdhp == NULL) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); - goto err; - } - if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); - goto err; - } - - 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_DTLS1_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_DTLS1_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_DTLS1_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 = - tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) - == 0) - { - SSLerr(SSL_F_DTLS1_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_DTLS1_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_DTLS1_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 four additional bytes - * to encode the entire ServerECDHParams - * structure. - */ - n = 4 + encodedlen; - - /* We'll generate the serverKeyExchange message - * explicitly so we can set these to NULLs - */ - r[0]=NULL; - r[1]=NULL; - r[2]=NULL; - r[3]=NULL; - } - else -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) - { - /* reserve size for record length and PSK identity hint*/ - n+=2+strlen(s->ctx->psk_identity_hint); - } - else -#endif /* !OPENSSL_NO_PSK */ - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_DTLS1_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->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) - { - if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher, NULL)) - == 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+DTLS1_HM_HEADER_LENGTH+kn)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF); - goto err; - } - d=(unsigned char *)s->init_buf->data; - p= &(d[DTLS1_HM_HEADER_LENGTH]); - - 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_kEECDH) - { - /* XXX: For now, we only support named (not generic) curves. - * In this situation, the serverKeyExchange message has: - * [1 byte CurveType], [2 byte CurveName] - * [1 byte length of encoded point], followed by - * the actual encoded point itself - */ - *p = NAMED_CURVE_TYPE; - p += 1; - *p = 0; - 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 - -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) - { - /* copy PSK identity hint */ - s2n(strlen(s->ctx->psk_identity_hint), p); - strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); - p+=strlen(s->ctx->psk_identity_hint); - } -#endif - - /* not anonymous */ - if (pkey != NULL) - { - /* n is the length of the params, they start at - * &(d[DTLS1_HM_HEADER_LENGTH]) 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[DTLS1_HM_HEADER_LENGTH]),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_DTLS1_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[DTLS1_HM_HEADER_LENGTH]),n); - if (!EVP_SignFinal(&md_ctx,&(p[2]), - (unsigned int *)&i,pkey)) - { - SSLerr(SSL_F_DTLS1_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[DTLS1_HM_HEADER_LENGTH]),n); - if (!EVP_SignFinal(&md_ctx,&(p[2]), - (unsigned int *)&i,pkey)) - { - SSLerr(SSL_F_DTLS1_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_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE); - goto f_err; - } - } - - d = dtls1_set_message_header(s, d, - SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n); - - /* we should now have things packed up, so lets send - * it off */ - s->init_num=n+DTLS1_HM_HEADER_LENGTH; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - s->state = SSL3_ST_SW_KEY_EXCH_B; - EVP_MD_CTX_cleanup(&md_ctx); - return(dtls1_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 dtls1_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; - unsigned int msg_len; - - if (s->state == SSL3_ST_SW_CERT_REQ_A) - { - buf=s->init_buf; - - d=p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); - - /* get the list of acceptable cert types */ - p++; - n=ssl3_get_req_cert_type(s,p); - d[0]=n; - p+=n; - n++; - - off=n; - p+=2; - n+=2; - - sk=SSL_get_client_CA_list(s); - nl=0; - if (sk != NULL) - { - for (i=0; idata[DTLS1_HM_HEADER_LENGTH+n]); - if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) - { - s2n(j,p); - i2d_X509_NAME(name,&p); - n+=2+j; - nl+=2+j; - } - else - { - d=p; - i2d_X509_NAME(name,&p); - j-=2; s2n(j,d); j+=2; - n+=j; - nl+=j; - } - } - } - /* else no CA names */ - p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+off]); - s2n(nl,p); - - d=(unsigned char *)buf->data; - *(d++)=SSL3_MT_CERTIFICATE_REQUEST; - l2n3(n,d); - s2n(s->d1->handshake_write_seq,d); - s->d1->handshake_write_seq++; - - /* we should now have things packed up, so lets send - * it off */ - - s->init_num=n+DTLS1_HM_HEADER_LENGTH; - s->init_off=0; -#ifdef NETSCAPE_HANG_BUG -/* XXX: what to do about this? */ - p=(unsigned char *)s->init_buf->data + s->init_num; - - /* do the header */ - *(p++)=SSL3_MT_SERVER_DONE; - *(p++)=0; - *(p++)=0; - *(p++)=0; - s->init_num += 4; -#endif - - /* XDTLS: set message header ? */ - msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; - dtls1_set_message_header(s, (void *)s->init_buf->data, - SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len); - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - - s->state = SSL3_ST_SW_CERT_REQ_B; - } - - /* SSL3_ST_SW_CERT_REQ_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); -err: - return(-1); - } - -int dtls1_send_server_certificate(SSL *s) - { - unsigned long l; - CERT_PKEY *cpk; - - if (s->state == SSL3_ST_SW_CERT_A) - { - cpk=ssl_get_server_send_pkey(s); - if (cpk == NULL) - { - /* VRS: allow null cert if auth == KRB5 */ - if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) || - (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); - return(0); - } - } - - l=dtls1_output_cert_chain(s,cpk); - s->state=SSL3_ST_SW_CERT_B; - s->init_num=(int)l; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_SW_CERT_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - -#ifndef OPENSSL_NO_TLSEXT -int dtls1_send_newsession_ticket(SSL *s) - { - if (s->state == SSL3_ST_SW_SESSION_TICKET_A) - { - unsigned char *p, *senc, *macstart; - int len, slen; - unsigned int hlen, msg_len; - EVP_CIPHER_CTX ctx; - HMAC_CTX hctx; - SSL_CTX *tctx = s->initial_ctx; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char key_name[16]; - - /* get session encoding length */ - slen = i2d_SSL_SESSION(s->session, NULL); - /* Some length values are 16 bits, so forget it if session is - * too long - */ - if (slen > 0xFF00) - return -1; - /* Grow buffer if need be: the length calculation is as - * follows 12 (DTLS handshake message header) + - * 4 (ticket lifetime hint) + 2 (ticket length) + - * 16 (key name) + max_iv_len (iv length) + - * session_length + max_enc_block_size (max encrypted session - * length) + max_md_size (HMAC). - */ - if (!BUF_MEM_grow(s->init_buf, - DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH + - EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) - return -1; - senc = OPENSSL_malloc(slen); - if (!senc) - return -1; - p = senc; - i2d_SSL_SESSION(s->session, &p); - - p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]); - EVP_CIPHER_CTX_init(&ctx); - HMAC_CTX_init(&hctx); - /* Initialize HMAC and cipher contexts. If callback present - * it does all the work otherwise use generated values - * from parent ctx. - */ - if (tctx->tlsext_ticket_key_cb) - { - if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, - &hctx, 1) < 0) - { - OPENSSL_free(senc); - return -1; - } - } - else - { - RAND_pseudo_bytes(iv, 16); - EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, iv); - HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL); - memcpy(key_name, tctx->tlsext_tick_key_name, 16); - } - l2n(s->session->tlsext_tick_lifetime_hint, p); - /* Skip ticket length for now */ - p += 2; - /* Output key name */ - macstart = p; - memcpy(p, key_name, 16); - p += 16; - /* output IV */ - memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); - p += EVP_CIPHER_CTX_iv_length(&ctx); - /* Encrypt session data */ - EVP_EncryptUpdate(&ctx, p, &len, senc, slen); - p += len; - EVP_EncryptFinal(&ctx, p, &len); - p += len; - EVP_CIPHER_CTX_cleanup(&ctx); - - HMAC_Update(&hctx, macstart, p - macstart); - HMAC_Final(&hctx, p, &hlen); - HMAC_CTX_cleanup(&hctx); - - p += hlen; - /* Now write out lengths: p points to end of data written */ - /* Total length */ - len = p - (unsigned char *)(s->init_buf->data); - /* Ticket length */ - p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4; - s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p); - - /* number of bytes to write */ - s->init_num= len; - s->state=SSL3_ST_SW_SESSION_TICKET_B; - s->init_off=0; - OPENSSL_free(senc); - - /* XDTLS: set message header ? */ - msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; - dtls1_set_message_header(s, (void *)s->init_buf->data, - SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len); - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_SW_SESSION_TICKET_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } -#endif