X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=02c8c10aa1629776a0e599c904129811d18648d5;hb=4aecfd4d9f366c849c9627ab666d1b1addc024e6;hp=41a5ba550361945c7900eb54de0c97fd4f938451;hpb=b77b58a398c8b9b4113f3fb6b48e162a3b8d4527;p=openssl.git diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 41a5ba5503..02c8c10aa1 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -154,6 +154,7 @@ #include #include "ssl_locl.h" #include "kssl_lcl.h" +#include "../crypto/constant_time_locl.h" #include #include #include @@ -169,6 +170,7 @@ #endif #include +#ifndef OPENSSL_NO_SSL3_METHOD static const SSL_METHOD *ssl3_get_server_method(int ver); static const SSL_METHOD *ssl3_get_server_method(int ver) @@ -179,6 +181,12 @@ static const SSL_METHOD *ssl3_get_server_method(int ver) return(NULL); } +IMPLEMENT_ssl3_meth_func(SSLv3_server_method, + ssl3_accept, + ssl_undefined_function, + ssl3_get_server_method) +#endif + #ifndef OPENSSL_NO_SRP static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { @@ -205,11 +213,6 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) } #endif -IMPLEMENT_ssl3_meth_func(SSLv3_server_method, - ssl3_accept, - ssl_undefined_function, - ssl3_get_server_method) - int ssl3_accept(SSL *s) { BUF_MEM *buf; @@ -272,6 +275,14 @@ int ssl3_accept(SSL *s) SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); return -1; } + + if (!ssl_security(s, SSL_SECOP_VERSION, 0, + s->version, NULL)) + { + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_VERSION_TOO_LOW); + return -1; + } + s->type=SSL_ST_ACCEPT; if (s->init_buf == NULL) @@ -283,6 +294,7 @@ int ssl3_accept(SSL *s) } if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); ret= -1; goto end; } @@ -298,6 +310,9 @@ int ssl3_accept(SSL *s) s->init_num=0; s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* Should have been reset by ssl3_get_finished, too. */ + s->s3->change_cipher_spec = 0; if (s->state != SSL_ST_RENEGOTIATE) { @@ -352,12 +367,11 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: - if (s->rwstate != SSL_X509_LOOKUP) - { - ret=ssl3_get_client_hello(s); - if (ret <= 0) goto end; - } + ret=ssl3_get_client_hello(s); + if (ret <= 0) goto end; #ifndef OPENSSL_NO_SRP + s->state = SSL3_ST_SR_CLNT_HELLO_D; + case SSL3_ST_SR_CLNT_HELLO_D: { int al; if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0) @@ -402,32 +416,16 @@ int ssl3_accept(SSL *s) s->state=SSL3_ST_SW_CHANGE_A; #endif else -#ifndef OPENSSL_NO_TLSEXT - s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A; -#else - s->state = SSL3_ST_SW_CERT_A; -#endif - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: - case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: - ret = tls1_send_server_supplemental_data(s, &skip); - if (ret <= 0) goto end; - - s->state = SSL3_ST_SW_CERT_A; + s->state = SSL3_ST_SW_CERT_A; s->init_num = 0; break; -#endif case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH or anon ECDH, */ /* normal PSK or KRB5 or SRP */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) - && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) + if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP)) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { ret=ssl3_send_server_certificate(s); if (ret <= 0) goto end; @@ -493,8 +491,8 @@ int ssl3_accept(SSL *s) /* SRP: send ServerKeyExchange */ || (alg_k & SSL_kSRP) #endif - || (alg_k & SSL_kEDH) - || (alg_k & SSL_kEECDH) + || (alg_k & SSL_kDHE) + || (alg_k & SSL_kECDHE) || ((alg_k & SSL_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) @@ -530,7 +528,9 @@ int ssl3_accept(SSL *s) * (against the specs, but s3_clnt.c accepts this for SSL 3) */ !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || /* never request cert in Kerberos ciphersuites */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || + /* don't request certificate for SRP auth */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) /* With normal PSK Certificates and * Certificate Requests are omitted */ || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) @@ -589,16 +589,7 @@ int ssl3_accept(SSL *s) s->state=s->s3->tmp.next_state; break; -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_SR_SUPPLEMENTAL_DATA_A: - case SSL3_ST_SR_SUPPLEMENTAL_DATA_B: - ret=tls1_get_client_supplemental_data(s); - if (ret <= 0) goto end; - s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; - s->state=SSL3_ST_SW_FLUSH; - s->init_num=0; - break; -#endif + case SSL3_ST_SR_CERT_A: case SSL3_ST_SR_CERT_B: /* Check for second client hello (MS SGC) */ @@ -607,10 +598,6 @@ int ssl3_accept(SSL *s) goto end; if (ret == 2) s->state = SSL3_ST_SR_CLNT_HELLO_C; -#ifndef OPENSSL_NO_TLSEXT - else if (ret == 3) - s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A; -#endif else { if (s->s3->tmp.cert_request) { @@ -700,7 +687,14 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: - + /* + * This *should* be the first time we enable CCS, but be + * extra careful about surrounding code changes. We need + * to set this here because we don't know if we're + * expecting a CertificateVerify or not. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; @@ -719,6 +713,19 @@ int ssl3_accept(SSL *s) #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) case SSL3_ST_SR_NEXT_PROTO_A: case SSL3_ST_SR_NEXT_PROTO_B: + /* + * Enable CCS for resumed handshakes with NPN. + * In a full handshake with NPN, we end up here through + * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was + * already set. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_next_proto(s); if (ret <= 0) goto end; s->init_num = 0; @@ -728,6 +735,18 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: + /* + * Enable CCS for resumed handshakes without NPN. + * In a full handshake, we end up here through + * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was + * already set. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; @@ -798,7 +817,9 @@ int ssl3_accept(SSL *s) s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; #else if (s->s3->next_proto_neg_seen) + { s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; + } else s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; #endif @@ -901,10 +922,6 @@ int ssl3_check_client_hello(SSL *s) &ok); if (!ok) return((int)n); s->s3->tmp.reuse_message = 1; -#ifndef OPENSSL_NO_TLSEXT - if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA) - return 3; -#endif if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { /* We only allow the client to restart the handshake once per @@ -950,6 +967,9 @@ int ssl3_get_client_hello(SSL *s) #endif STACK_OF(SSL_CIPHER) *ciphers=NULL; + if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet) + goto retry_cert; + /* We do this so that we will respond with our native type. * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, * This down switching should be handled by a different method. @@ -1035,7 +1055,16 @@ int ssl3_get_client_hello(SSL *s) else { i=ssl_get_prev_session(s, p, j, d + n); - if (i == 1) + /* + * Only resume if the session's version matches the negotiated + * version. + * RFC 5246 does not provide much useful advice on resumption + * with a different protocol version. It doesn't forbid it but + * the sanity of such behaviour would be questionable. + * In practice, clients do not accept a version mismatch and + * will abort the handshake with an error. + */ + if (i == 1 && s->version == s->session->ssl_version) { /* previous session */ s->hit=1; } @@ -1161,14 +1190,15 @@ int ssl3_get_client_hello(SSL *s) id=s->session->cipher->id; #ifdef CIPHER_DEBUG - printf("client sent %d ciphers\n",sk_num(ciphers)); + fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers)); #endif for (i=0; iid == id) { @@ -1303,7 +1333,7 @@ int ssl3_get_client_hello(SSL *s) int m, comp_id = s->session->compress_meth; /* Perform sanity checks on resumed compression algorithm */ /* Can't disable compression */ - if (s->options & SSL_OP_NO_COMPRESSION) + if (!ssl_allow_compression(s)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); goto f_err; @@ -1338,7 +1368,7 @@ int ssl3_get_client_hello(SSL *s) } else if (s->hit) comp = NULL; - else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) + else if (ssl_allow_compression(s) && s->ctx->comp_methods) { /* See if we have a match */ int m,nn,o,v,done=0; @@ -1393,13 +1423,28 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } ciphers=NULL; + if (!tls1_set_server_sigalgs(s)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } /* Let cert callback update server certificates if required */ - if (s->cert->cert_cb - && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0) + retry_cert: + if (s->cert->cert_cb) { - al=SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR); - goto f_err; + int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (rv == 0) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR); + goto f_err; + } + if (rv < 0) + { + s->rwstate=SSL_X509_LOOKUP; + return -1; + } + s->rwstate = SSL_NOTHING; } c=ssl3_choose_cipher(s,s->session->ciphers, SSL_get_ciphers(s)); @@ -1414,7 +1459,7 @@ int ssl3_get_client_hello(SSL *s) /* check whether we should disable session resumption */ if (s->not_resumable_session_cb != NULL) s->session->not_resumable=s->not_resumable_session_cb(s, - ((c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)) != 0)); + ((c->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) != 0)); if (s->session->not_resumable) /* do not send a session ticket */ s->tlsext_ticket_expected = 0; @@ -1464,7 +1509,7 @@ int ssl3_get_client_hello(SSL *s) * ssl version is set - sslv3 * s->session - The ssl session has been setup. * s->hit - session reuse flag - * s->tmp.new_cipher - the new cipher to use. + * s->s3->tmp.new_cipher- the new cipher to use. */ /* Handles TLS extensions that we couldn't check earlier */ @@ -1493,6 +1538,7 @@ int ssl3_send_server_hello(SSL *s) unsigned char *buf; unsigned char *p,*d; int i,sl; + int al = 0; unsigned long l; if (s->state == SSL3_ST_SW_SRVR_HELLO_A) @@ -1562,8 +1608,9 @@ int ssl3_send_server_hello(SSL *s) SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT); return -1; } - if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); return -1; } @@ -1663,9 +1710,20 @@ int ssl3_send_server_key_exchange(SSL *s) else #endif #ifndef OPENSSL_NO_DH - if (type & SSL_kEDH) + if (type & SSL_kDHE) { - dhp=cert->dh_tmp; + if (s->cert->dh_tmp_auto) + { + dhp = ssl_get_auto_dh(s); + if (dhp == NULL) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto f_err; + } + } + else + 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), @@ -1676,14 +1734,22 @@ int ssl3_send_server_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); goto f_err; } - + if (!ssl_security(s, SSL_SECOP_TMP_DH, + DH_security_bits(dhp), 0, dhp)) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } if (s->s3->tmp.dh != NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } - if ((dh=DHparams_dup(dhp)) == NULL) + if (s->cert->dh_tmp_auto) + dh = dhp; + else if ((dh=DHparams_dup(dhp)) == NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; @@ -1719,7 +1785,7 @@ int ssl3_send_server_key_exchange(SSL *s) else #endif #ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) + if (type & SSL_kECDHE) { const EC_GROUP *group; @@ -1884,7 +1950,7 @@ int ssl3_send_server_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } - for (i=0; r[i] != NULL && i<4; i++) + for (i=0; i < 4 && r[i] != NULL; i++) { nr[i]=BN_num_bytes(r[i]); #ifndef OPENSSL_NO_SRP @@ -1895,7 +1961,7 @@ int ssl3_send_server_key_exchange(SSL *s) n+=2+nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md)) @@ -1919,7 +1985,7 @@ int ssl3_send_server_key_exchange(SSL *s) } d = p = ssl_handshake_start(s); - for (i=0; r[i] != NULL && i<4; i++) + for (i=0; i < 4 && r[i] != NULL; i++) { #ifndef OPENSSL_NO_SRP if ((i == 2) && (type & SSL_kSRP)) @@ -1935,7 +2001,7 @@ int ssl3_send_server_key_exchange(SSL *s) } #ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) + if (type & SSL_kECDHE) { /* XXX: For now, we only support named (not generic) curves. * In this situation, the serverKeyExchange message has: @@ -2088,9 +2154,13 @@ int ssl3_send_certificate_request(SSL *s) if (SSL_USE_SIGALGS(s)) { const unsigned char *psigs; + unsigned char *etmp = p; nl = tls12_get_psigalgs(s, &psigs); - s2n(nl, p); - memcpy(p, psigs, nl); + /* Skip over length for now */ + p += 2; + nl = tls12_copy_sigalgs(s, p, psigs, nl); + /* Now fill in length */ + s2n(nl, etmp); p += nl; n += nl + 2; } @@ -2139,6 +2209,11 @@ int ssl3_send_certificate_request(SSL *s) #ifdef NETSCAPE_HANG_BUG if (!SSL_IS_DTLS(s)) { + if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) + { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB); + goto err; + } p=(unsigned char *)s->init_buf->data + s->init_num; /* do the header */ *(p++)=SSL3_MT_SERVER_DONE; @@ -2199,8 +2274,9 @@ int ssl3_get_client_key_exchange(SSL *s) if (alg_k & SSL_kRSA) { unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - int decrypt_len, decrypt_good_mask; - unsigned char version_good; + int decrypt_len; + unsigned char decrypt_good, version_good; + size_t j; /* FIX THIS UP EAY EAY EAY EAY */ if (s->s3->tmp.use_rsa_tmp) @@ -2239,8 +2315,9 @@ int ssl3_get_client_key_exchange(SSL *s) { if (!(s->options & SSL_OP_TLS_D5_BUG)) { + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto err; + goto f_err; } else p-=2; @@ -2249,6 +2326,20 @@ int ssl3_get_client_key_exchange(SSL *s) n=i; } + /* + * Reject overly short RSA ciphertext because we want to be sure + * that the buffer size makes it safe to iterate over the entire + * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The + * actual expected size is larger due to RSA padding, but the + * bound is sufficient to be safe. + */ + if (n < SSL_MAX_MASTER_KEY_LENGTH) + { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; + } + /* We must not leak whether a decryption failure occurs because * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see * RFC 2246, section 7.4.7.1). The code follows that advice of @@ -2264,18 +2355,18 @@ int ssl3_get_client_key_exchange(SSL *s) ERR_clear_error(); /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. - * decrypt_good_mask will be zero if so and non-zero otherwise. */ - decrypt_good_mask = decrypt_len ^ SSL_MAX_MASTER_KEY_LENGTH; + * decrypt_good will be 0xff if so and zero otherwise. */ + decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH); /* If the version in the decrypted pre-master secret is correct - * then version_good will be zero. The Klima-Pokorny-Rosa - * extension of Bleichenbacher's attack + * then version_good will be 0xff, otherwise it'll be zero. + * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack * (http://eprint.iacr.org/2003/052/) exploits the version * number check as a "bad version oracle". Thus version checks * are done in constant time and are treated like any other * decryption error. */ - version_good = p[0] ^ (s->client_version>>8); - version_good |= p[1] ^ (s->client_version&0xff); + version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8)); + version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff)); /* The premaster secret must contain the same version number as * the ClientHello to detect version rollback attacks @@ -2286,67 +2377,38 @@ int ssl3_get_client_key_exchange(SSL *s) * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */ if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { - unsigned char workaround_mask = version_good; - unsigned char workaround; - - /* workaround_mask will be 0xff if version_good is - * non-zero (i.e. the version match failed). Otherwise - * it'll be 0x00. */ - workaround_mask |= workaround_mask >> 4; - workaround_mask |= workaround_mask >> 2; - workaround_mask |= workaround_mask >> 1; - workaround_mask = ~((workaround_mask & 1) - 1); - - workaround = p[0] ^ (s->version>>8); - workaround |= p[1] ^ (s->version&0xff); - - /* If workaround_mask is 0xff (i.e. there was a version - * mismatch) then we copy the value of workaround over - * version_good. */ - version_good = (workaround & workaround_mask) | - (version_good & ~workaround_mask); - } - - /* If any bits in version_good are set then they'll poision - * decrypt_good_mask and cause rand_premaster_secret to be - * used. */ - decrypt_good_mask |= version_good; - - /* decrypt_good_mask will be zero iff decrypt_len == - * SSL_MAX_MASTER_KEY_LENGTH and the version check passed. We - * fold the bottom 32 bits of it with an OR so that the LSB - * will be zero iff everything is good. This assumes that we'll - * never decrypt a value > 2**31 bytes, which seems safe. */ - decrypt_good_mask |= decrypt_good_mask >> 16; - decrypt_good_mask |= decrypt_good_mask >> 8; - decrypt_good_mask |= decrypt_good_mask >> 4; - decrypt_good_mask |= decrypt_good_mask >> 2; - decrypt_good_mask |= decrypt_good_mask >> 1; - /* Now select only the LSB and subtract one. If decrypt_len == - * SSL_MAX_MASTER_KEY_LENGTH and the version check passed then - * decrypt_good_mask will be all ones. Otherwise it'll be all - * zeros. */ - decrypt_good_mask &= 1; - decrypt_good_mask--; - - /* Now copy rand_premaster_secret over p using - * decrypt_good_mask. */ - for (i = 0; i < (int) sizeof(rand_premaster_secret); i++) - { - p[i] = (p[i] & decrypt_good_mask) | - (rand_premaster_secret[i] & ~decrypt_good_mask); + unsigned char workaround_good; + workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8)); + workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff)); + version_good |= workaround_good; + } + + /* Both decryption and version must be good for decrypt_good + * to remain non-zero (0xff). */ + decrypt_good &= version_good; + + /* + * Now copy rand_premaster_secret over from p using + * decrypt_good_mask. If decryption failed, then p does not + * contain valid plaintext, however, a check above guarantees + * it is still sufficiently large to read from. + */ + for (j = 0; j < sizeof(rand_premaster_secret); j++) + { + p[j] = constant_time_select_8(decrypt_good, p[j], + rand_premaster_secret[j]); } s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, - p,i); - OPENSSL_cleanse(p,i); + p,sizeof(rand_premaster_secret)); + OPENSSL_cleanse(p,sizeof(rand_premaster_secret)); } else #endif #ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + if (alg_k & (SSL_kDHE|SSL_kDHr|SSL_kDHd)) { int idx = -1; EVP_PKEY *skey = NULL; @@ -2518,10 +2580,10 @@ int ssl3_get_client_key_exchange(SSL *s) &kssl_err)) != 0) { #ifdef KSSL_DEBUG - printf("kssl_sget_tkt rtn %d [%d]\n", + fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n", krb5rc, kssl_err.reason); if (kssl_err.text) - printf("kssl_err text= %s\n", kssl_err.text); + fprintf(stderr,"kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); @@ -2535,10 +2597,10 @@ int ssl3_get_client_key_exchange(SSL *s) &authtime, &kssl_err)) != 0) { #ifdef KSSL_DEBUG - printf("kssl_check_authent rtn %d [%d]\n", + fprintf(stderr,"kssl_check_authent rtn %d [%d]\n", krb5rc, kssl_err.reason); if (kssl_err.text) - printf("kssl_err text= %s\n", kssl_err.text); + fprintf(stderr,"kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); @@ -2638,7 +2700,7 @@ int ssl3_get_client_key_exchange(SSL *s) #endif /* OPENSSL_NO_KRB5 */ #ifndef OPENSSL_NO_ECDH - if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) + if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { int ret = 1; int field_size = 0; @@ -2691,7 +2753,7 @@ int ssl3_get_client_key_exchange(SSL *s) { /* Client Publickey was in Client Certificate */ - if (alg_k & SSL_kEECDH) + if (alg_k & SSL_kECDHE) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY); @@ -2906,6 +2968,13 @@ int ssl3_get_client_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); goto err; } + if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 + || BN_is_zero(s->srp_ctx.A)) + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_PARAMETERS); + goto f_err; + } if (s->session->srp_username != NULL) OPENSSL_free(s->session->srp_username); s->session->srp_username = BUF_strdup(s->srp_ctx.login); @@ -2934,6 +3003,8 @@ int ssl3_get_client_key_exchange(SSL *s) unsigned char premaster_secret[32], *start; size_t outlen=32, inlen; unsigned long alg_a; + int Ttag, Tclass; + long Tlen; /* Get our certificate private key*/ alg_a = s->s3->tmp.new_cipher->algorithm_auth; @@ -2955,26 +3026,15 @@ int ssl3_get_client_key_exchange(SSL *s) ERR_clear_error(); } /* Decrypt session key */ - if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - goto gerr; - } - if (p[1] == 0x81) - { - start = p+3; - inlen = p[2]; - } - else if (p[1] < 0x80) - { - start = p+2; - inlen = p[1]; - } - else + if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || + Ttag != V_ASN1_SEQUENCE || + Tclass != V_ASN1_UNIVERSAL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); goto gerr; } + start = p; + inlen = Tlen; if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) { @@ -3038,7 +3098,7 @@ int ssl3_get_cert_verify(SSL *s) SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, -1, - 516, /* Enough for 4096 bit RSA key with TLS v1.2 */ + SSL3_RT_MAX_PLAIN_LENGTH, &ok); if (!ok) return((int)n); @@ -3386,6 +3446,7 @@ int ssl3_get_client_certificate(SSL *s) } else { + EVP_PKEY *pkey; i=ssl_verify_cert_chain(s,sk); if (i <= 0) { @@ -3393,6 +3454,21 @@ int ssl3_get_client_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); goto f_err; } + if (i > 1) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, i); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + pkey = X509_get_pubkey(sk_X509_value(sk, 0)); + if (pkey == NULL) + { + al=SSL3_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto f_err; + } + EVP_PKEY_free(pkey); } if (s->session->peer != NULL) /* This should not be needed */ @@ -3449,7 +3525,11 @@ int ssl3_send_server_certificate(SSL *s) } } - ssl3_output_cert_chain(s,cpk); + if (!ssl3_output_cert_chain(s,cpk)) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); + return(0); + } s->state=SSL3_ST_SW_CERT_B; } @@ -3689,153 +3769,4 @@ int ssl3_get_next_proto(SSL *s) } # endif -int tls1_send_server_supplemental_data(SSL *s, int *skip) - { - if (s->ctx->srv_supp_data_records_count) - { - unsigned char *p = NULL; - unsigned char *size_loc = NULL; - srv_supp_data_record *record = NULL; - size_t length = 0; - size_t i = 0; - - for (i = 0; i < s->ctx->srv_supp_data_records_count; i++) - { - const unsigned char *out = NULL; - unsigned short outlen = 0; - int cb_retval = 0; - record = &s->ctx->srv_supp_data_records[i]; - - /* NULL callback or -1 omits supp data entry */ - if (!record->fn1) - continue; - cb_retval = record->fn1(s, record->supp_data_type, - &out, &outlen, - record->arg); - if (cb_retval == -1) - continue; /* skip this supp data entry */ - if (cb_retval == 0) - { - SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length) - { - SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - /* write supp data entry... - * if first entry, write handshake message type - * jump back to write length at end */ - if (length == 0) - { - /* 1 byte message type + 3 bytes for - * message length */ - if (!BUF_MEM_grow_clean(s->init_buf, 4)) - { - SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; - /* hold on to length field to update later */ - size_loc = p; - /* skip over handshake length field (3 - * bytes) and supp_data length field - * (3 bytes) */ - p += 3 + 3; - length += 1 +3 +3; - } - /* 2 byte supp data type + 2 byte length + outlen */ - if (!BUF_MEM_grow(s->init_buf, outlen + 4)) - { - SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - s2n(record->supp_data_type, p); - s2n(outlen, p); - memcpy(p, out, outlen); - /* update length to supp data type (2 bytes) + - * supp data length (2 bytes) + supp data */ - length += (outlen + 4); - p += outlen; - } - if (length > 0) - { - /* write handshake length */ - l2n3(length - 4, size_loc); - /* supp_data length */ - l2n3(length - 7, size_loc); - s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B; - s->init_num = length; - s->init_off = 0; - - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); - } - } - - /* no supp data message sent */ - *skip = 1; - s->init_num = 0; - s->init_off = 0; - return 1; - } - -int tls1_get_client_supplemental_data(SSL *s) - { - int al = 0; - int cb_retval = 0; - int ok; - long n; - const unsigned char *p, *d; - unsigned short supp_data_entry_type = 0; - unsigned long supp_data_entry_len = 0; - unsigned long supp_data_len = 0; - size_t i = 0; - - n=s->method->ssl_get_message(s, - SSL3_ST_SR_SUPPLEMENTAL_DATA_A, - SSL3_ST_SR_SUPPLEMENTAL_DATA_B, - SSL3_MT_SUPPLEMENTAL_DATA, - /* use default limit */ - TLSEXT_MAXLEN_supplemental_data, - &ok); - - if (!ok) return((int)n); - - p = (unsigned char *)s->init_msg; - d = p; - - /* The message cannot be empty */ - if (n < 3) - { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH); - goto f_err; - } - n2l3(p, supp_data_len); - while (pctx->srv_supp_data_records_count; i++) - { - if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2) - { - cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg); - if (cb_retval == 0) - { - SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB); - goto f_err; - } - } - } - p+=supp_data_entry_len; - } - return 1; -f_err: - ssl3_send_alert(s,SSL3_AL_FATAL,al); - return -1; - } #endif