X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=8bdb0829997a8ffcbf2f8054d07b16d098be3eb0;hb=efcdbcbeda556876c0147dca21d51610de30dfd9;hp=fd4c87e9e6eb53280ea21f9a1e168b89cfa22357;hpb=657da85eea3a5825b2dd25ff25b99ec206c48136;p=openssl.git diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index fd4c87e9e6..8bdb082999 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -874,7 +874,11 @@ int ssl3_get_client_hello(SSL *s) if (!ok) return ((int)n); s->first_packet = 0; - PACKET_buf_init(&pkt, s->init_msg, n); + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } /* First lets get s->client_version set correctly */ if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) { @@ -1014,6 +1018,9 @@ int ssl3_get_client_hello(SSL *s) if (!PACKET_get_net_2(&pkt, &csl) || !PACKET_get_net_2(&pkt, &sil) || !PACKET_get_net_2(&pkt, &cl)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; } if (csl == 0) { @@ -1052,7 +1059,7 @@ int ssl3_get_client_hello(SSL *s) memset(s->s3->client_random, 0, SSL3_RANDOM_SIZE); if (!PACKET_peek_copy_bytes(&pkt, s->s3->client_random, i) || !PACKET_forward(&pkt, cl) - || !PACKET_remaining(&pkt) == 0) { + || PACKET_remaining(&pkt) != 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; @@ -2204,10 +2211,10 @@ int ssl3_send_certificate_request(SSL *s) int ssl3_get_client_key_exchange(SSL *s) { - int i, al, ok; + unsigned int i; + int al, ok; long n; unsigned long alg_k; - unsigned char *p; #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; EVP_PKEY *pkey = NULL; @@ -2222,6 +2229,9 @@ int ssl3_get_client_key_exchange(SSL *s) EC_POINT *clnt_ecpoint = NULL; BN_CTX *bn_ctx = NULL; #endif + PACKET pkt; + unsigned char *data; + size_t remain; n = s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A, @@ -2230,7 +2240,11 @@ int ssl3_get_client_key_exchange(SSL *s) if (!ok) return ((int)n); - p = (unsigned char *)s->init_msg; + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } alg_k = s->s3->tmp.new_cipher->algorithm_mkey; @@ -2239,13 +2253,8 @@ int ssl3_get_client_key_exchange(SSL *s) if (alg_k & SSL_PSK) { unsigned char psk[PSK_MAX_PSK_LEN]; size_t psklen; - if (n < 2) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - n2s(p, i); - if (i + 2 > n) { + + if (!PACKET_get_net_2(&pkt, &i)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -2264,14 +2273,20 @@ int ssl3_get_client_key_exchange(SSL *s) } OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strndup((char *)p, i); - + s->session->psk_identity = OPENSSL_malloc(i + 1); if (s->session->psk_identity == NULL) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; } + if (!PACKET_copy_bytes(&pkt, (unsigned char *)s->session->psk_identity, + i)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + s->session->psk_identity[i] = '\0'; psklen = s->psk_server_callback(s, s->session->psk_identity, psk, sizeof(psk)); @@ -2301,13 +2316,10 @@ int ssl3_get_client_key_exchange(SSL *s) } s->s3->tmp.psklen = psklen; - - n -= i + 2; - p += i; } if (alg_k & SSL_kPSK) { /* Identity extracted earlier: should be nothing left */ - if (n != 0) { + if (PACKET_remaining(&pkt) != 0) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; @@ -2355,17 +2367,34 @@ int ssl3_get_client_key_exchange(SSL *s) /* TLS and [incidentally] DTLS{0xFEFF} */ if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { - n2s(p, i); - if (n != i + 2) { + if (!PACKET_get_net_2(&pkt, &i)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + remain = PACKET_remaining(&pkt); + if (remain != i) { 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 f_err; - } else - p -= 2; - } else - n = i; + } else { + remain += 2; + if (!PACKET_back(&pkt, 2)) { + /* + * We already read these 2 bytes so this should never + * fail + */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + } + } + } else { + remain = PACKET_remaining(&pkt); } /* @@ -2375,13 +2404,20 @@ int ssl3_get_client_key_exchange(SSL *s) * actual expected size is larger due to RSA padding, but the * bound is sufficient to be safe. */ - if (n < SSL_MAX_MASTER_KEY_LENGTH) { + + if (remain < 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; } + if (!PACKET_get_bytes(&pkt, &data, remain)) { + /* We already checked we had enough data so this shouldn't happen */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + 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, @@ -2394,7 +2430,7 @@ int ssl3_get_client_key_exchange(SSL *s) sizeof(rand_premaster_secret)) <= 0) goto err; decrypt_len = - RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); + RSA_private_decrypt(remain, data, data, rsa, RSA_PKCS1_PADDING); ERR_clear_error(); /* @@ -2413,9 +2449,9 @@ int ssl3_get_client_key_exchange(SSL *s) * constant time and are treated like any other decryption error. */ version_good = - constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8)); + constant_time_eq_8(data[0], (unsigned)(s->client_version >> 8)); version_good &= - constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff)); + constant_time_eq_8(data[1], (unsigned)(s->client_version & 0xff)); /* * The premaster secret must contain the same version number as the @@ -2429,9 +2465,9 @@ int ssl3_get_client_key_exchange(SSL *s) if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { unsigned char workaround_good; workaround_good = - constant_time_eq_8(p[0], (unsigned)(s->version >> 8)); + constant_time_eq_8(data[0], (unsigned)(s->version >> 8)); workaround_good &= - constant_time_eq_8(p[1], (unsigned)(s->version & 0xff)); + constant_time_eq_8(data[1], (unsigned)(s->version & 0xff)); version_good |= workaround_good; } @@ -2448,11 +2484,12 @@ int ssl3_get_client_key_exchange(SSL *s) * 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], + data[j] = constant_time_select_8(decrypt_good, data[j], rand_premaster_secret[j]); } - if (!ssl_generate_master_secret(s, p, sizeof(rand_premaster_secret), 0)) { + if (!ssl_generate_master_secret(s, data, sizeof(rand_premaster_secret), + 0)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -2463,9 +2500,15 @@ int ssl3_get_client_key_exchange(SSL *s) if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd | SSL_kDHEPSK)) { int idx = -1; EVP_PKEY *skey = NULL; - if (n > 1) { - n2s(p, i); - } else { + size_t bookm; + unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8]; + + if (!PACKET_get_bookmark(&pkt, &bookm)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } + if (!PACKET_get_net_2(&pkt, &i)) { if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, @@ -2474,14 +2517,19 @@ int ssl3_get_client_key_exchange(SSL *s) } i = 0; } - if (n && n != i + 2) { + if (PACKET_remaining(&pkt) != i) { if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); goto err; } else { - p -= 2; - i = (int)n; + if (!PACKET_goto_bookmark(&pkt, bookm)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + i = PACKET_remaining(&pkt); } } if (alg_k & SSL_kDHr) @@ -2521,14 +2569,22 @@ int ssl3_get_client_key_exchange(SSL *s) } EVP_PKEY_free(clkey); pub = dh_clnt->pub_key; - } else - pub = BN_bin2bn(p, i, NULL); + } else { + if (!PACKET_get_bytes(&pkt, &data, i)) { + /* We already checked we have enough data */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + pub = BN_bin2bn(data, i, NULL); + } if (pub == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); goto err; } - i = DH_compute_key(p, pub, dh_srvr); + i = DH_compute_key(shared, pub, dh_srvr); if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); @@ -2543,7 +2599,7 @@ int ssl3_get_client_key_exchange(SSL *s) else BN_clear_free(pub); pub = NULL; - if (!ssl_generate_master_secret(s, p, i, 0)) { + if (!ssl_generate_master_secret(s, shared, i, 0)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -2560,6 +2616,7 @@ int ssl3_get_client_key_exchange(SSL *s) const EC_KEY *tkey; const EC_GROUP *group; const BIGNUM *priv_key; + unsigned char *shared; /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) { @@ -2638,21 +2695,21 @@ int ssl3_get_client_key_exchange(SSL *s) } /* Get encoded point length */ - i = *p; - p += 1; - if (n != 1 + i) { + if (!PACKET_get_1(&pkt, &i)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + if (!PACKET_get_bytes(&pkt, &data, i) + || PACKET_remaining(&pkt) != 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { + if (EC_POINT_oct2point(group, clnt_ecpoint, data, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - /* - * p is pointing to somewhere in the buffer currently, so set it - * to the start - */ - p = (unsigned char *)s->init_buf->data; } /* Compute the shared pre-master secret */ @@ -2661,10 +2718,16 @@ int ssl3_get_client_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); goto err; } - i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh, - NULL); + shared = OPENSSL_malloc((field_size + 7) / 8); + if (shared == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + i = ECDH_compute_key(shared, (field_size + 7) / 8, clnt_ecpoint, + srvr_ecdh, NULL); if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + OPENSSL_free(shared); goto err; } @@ -2675,7 +2738,7 @@ int ssl3_get_client_key_exchange(SSL *s) EC_KEY_free(s->s3->tmp.ecdh); s->s3->tmp.ecdh = NULL; - if (!ssl_generate_master_secret(s, p, i, 0)) { + if (!ssl_generate_master_secret(s, shared, i, 1)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -2685,17 +2748,13 @@ int ssl3_get_client_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { - int param_len; - - n2s(p, i); - param_len = i + 2; - if (param_len > n) { + if (!PACKET_get_net_2(&pkt, &i) + || !PACKET_get_bytes(&pkt, &data, i)) { al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_SRP_A_LENGTH); + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BAD_SRP_A_LENGTH); goto f_err; } - if ((s->srp_ctx.A = BN_bin2bn(p, i, NULL)) == NULL) { + if ((s->srp_ctx.A = BN_bin2bn(data, i, NULL)) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB); goto err; } @@ -2717,8 +2776,6 @@ int ssl3_get_client_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } - - p += i; } else #endif /* OPENSSL_NO_SRP */ if (alg_k & SSL_kGOST) { @@ -2733,9 +2790,7 @@ int ssl3_get_client_key_exchange(SSL *s) /* Get our certificate private key */ alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (alg_a & SSL_aGOST94) - pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; - else if (alg_a & SSL_aGOST01) + if (alg_a & SSL_aGOST01) pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); @@ -2752,15 +2807,20 @@ int ssl3_get_client_key_exchange(SSL *s) ERR_clear_error(); } /* Decrypt session key */ + if (!PACKET_get_bytes(&pkt, &data, n)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } if (ASN1_get_object - ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, + ((const unsigned char **)&data, &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; + start = data; inlen = Tlen; if (EVP_PKEY_decrypt (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { @@ -2816,13 +2876,15 @@ int ssl3_get_client_key_exchange(SSL *s) int ssl3_get_cert_verify(SSL *s) { EVP_PKEY *pkey = NULL; - unsigned char *p; + unsigned char *sig, *data; int al, ok, ret = 0; long n; int type = 0, i, j; + unsigned int len; X509 *peer; const EVP_MD *md = NULL; EVP_MD_CTX mctx; + PACKET pkt; EVP_MD_CTX_init(&mctx); /* @@ -2859,18 +2921,27 @@ int ssl3_get_cert_verify(SSL *s) } /* we now have a signature that we need to verify */ - p = (unsigned char *)s->init_msg; + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } /* Check for broken implementations of GOST ciphersuites */ /* * If key is GOST and n is exactly 64, it is bare signature without * length field */ - if (n == 64 && (pkey->type == NID_id_GostR3410_94 || - pkey->type == NID_id_GostR3410_2001)) { - i = 64; + if (n == 64 && pkey->type == NID_id_GostR3410_2001) { + len = 64; } else { if (SSL_USE_SIGALGS(s)) { - int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + int rv; + + if (!PACKET_get_bytes(&pkt, &sig, 2)) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + rv = tls12_check_peer_sigalg(&md, s, sig, pkey); if (rv == -1) { al = SSL_AD_INTERNAL_ERROR; goto f_err; @@ -2881,23 +2952,24 @@ int ssl3_get_cert_verify(SSL *s) #ifdef SSL_DEBUG fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); #endif - p += 2; - n -= 2; } - n2s(p, i); - n -= 2; - if (i > n) { + if (!PACKET_get_net_2(&pkt, &len)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; } } j = EVP_PKEY_size(pkey); - if ((i > j) || (n > j) || (n <= 0)) { + if (((int)len > j) || ((int)PACKET_remaining(&pkt) > j) || (n <= 0)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); al = SSL_AD_DECODE_ERROR; goto f_err; } + if (!PACKET_get_bytes(&pkt, &data, len)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } if (SSL_USE_SIGALGS(s)) { long hdatalen = 0; @@ -2919,7 +2991,7 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } - if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { + if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); goto f_err; @@ -2928,7 +3000,7 @@ int ssl3_get_cert_verify(SSL *s) #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len, pkey->pkey.rsa); if (i < 0) { al = SSL_AD_DECRYPT_ERROR; @@ -2946,7 +3018,7 @@ int ssl3_get_cert_verify(SSL *s) if (pkey->type == EVP_PKEY_DSA) { j = DSA_verify(pkey->save_type, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); + SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa); if (j <= 0) { /* bad signature */ al = SSL_AD_DECRYPT_ERROR; @@ -2959,7 +3031,7 @@ int ssl3_get_cert_verify(SSL *s) if (pkey->type == EVP_PKEY_EC) { j = ECDSA_verify(pkey->save_type, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); + SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec); if (j <= 0) { /* bad signature */ al = SSL_AD_DECRYPT_ERROR; @@ -2968,17 +3040,16 @@ int ssl3_get_cert_verify(SSL *s) } } else #endif - if (pkey->type == NID_id_GostR3410_94 - || pkey->type == NID_id_GostR3410_2001) { + if (pkey->type == NID_id_GostR3410_2001) { unsigned char signature[64]; int idx; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); EVP_PKEY_verify_init(pctx); - if (i != 64) { - fprintf(stderr, "GOST signature length is %d", i); + if (len != 64) { + fprintf(stderr, "GOST signature length is %d", len); } for (idx = 0; idx < 64; idx++) { - signature[63 - idx] = p[idx]; + signature[63 - idx] = data[idx]; } j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, 32); @@ -3012,10 +3083,11 @@ int ssl3_get_client_certificate(SSL *s) { int i, ok, al, ret = -1; X509 *x = NULL; - unsigned long l, nc, llen, n; - const unsigned char *p, *q; - unsigned char *d; + unsigned long l, llen, n; + const unsigned char *certstart; + unsigned char *certbytes; STACK_OF(X509) *sk = NULL; + PACKET pkt, spkt; n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, @@ -3051,35 +3123,42 @@ int ssl3_get_client_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } - p = d = (unsigned char *)s->init_msg; + + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + goto f_err; + } if ((sk = sk_X509_new_null()) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); goto done; } - n2l3(p, llen); - if (llen + 3 != n) { + if (!PACKET_get_net_3(&pkt, &llen) + || !PACKET_get_sub_packet(&pkt, &spkt, llen) + || PACKET_remaining(&pkt) != 0) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); goto f_err; } - for (nc = 0; nc < llen;) { - n2l3(p, l); - if ((l + nc + 3) > llen) { + + while (PACKET_remaining(&spkt) > 0) { + if (!PACKET_get_net_3(&spkt, &l) + || !PACKET_get_bytes(&spkt, &certbytes, l)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } - q = p; - x = d2i_X509(NULL, &p, l); + certstart = certbytes; + x = d2i_X509(NULL, (const unsigned char **)&certbytes, l); if (x == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); goto done; } - if (p != (q + l)) { + if (certbytes != (certstart + l)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_CERT_LENGTH_MISMATCH); @@ -3090,7 +3169,6 @@ int ssl3_get_client_certificate(SSL *s) goto done; } x = NULL; - nc += l + 3; } if (sk_X509_num(sk) <= 0) { @@ -3380,9 +3458,9 @@ int ssl3_send_cert_status(SSL *s) int ssl3_get_next_proto(SSL *s) { int ok; - int proto_len, padding_len; + unsigned int proto_len, padding_len; long n; - const unsigned char *p; + PACKET pkt; /* * Clients cannot send a NextProtocol message if we didn't see the @@ -3416,11 +3494,13 @@ int ssl3_get_next_proto(SSL *s) } if (n < 2) { - s->state = SSL_ST_ERR; - return 0; /* The body must be > 1 bytes long */ + goto err; /* The body must be > 1 bytes long */ } - p = (unsigned char *)s->init_msg; + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_INTERNAL_ERROR); + goto err; + } /*- * The payload looks like: @@ -3429,27 +3509,30 @@ int ssl3_get_next_proto(SSL *s) * uint8 padding_len; * uint8 padding[padding_len]; */ - proto_len = p[0]; - if (proto_len + 2 > s->init_num) { - s->state = SSL_ST_ERR; - return 0; - } - padding_len = p[proto_len + 1]; - if (proto_len + padding_len + 2 != s->init_num) { - s->state = SSL_ST_ERR; - return 0; + if (!PACKET_get_1(&pkt, &proto_len)){ + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_LENGTH_MISMATCH); + goto err; } s->next_proto_negotiated = OPENSSL_malloc(proto_len); - if (!s->next_proto_negotiated) { + if (s->next_proto_negotiated == NULL) { SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE); - s->state = SSL_ST_ERR; - return 0; + goto err; + } + + if (!PACKET_copy_bytes(&pkt, s->next_proto_negotiated, proto_len) + || !PACKET_get_1(&pkt, &padding_len) + || PACKET_remaining(&pkt) != padding_len) { + OPENSSL_free(s->next_proto_negotiated); + s->next_proto_negotiated = NULL; + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_LENGTH_MISMATCH); + goto err; } - memcpy(s->next_proto_negotiated, p + 1, proto_len); - s->next_proto_negotiated_len = proto_len; return 1; +err: + s->state = SSL_ST_ERR; + return 0; } #endif