From 3213bed728d15087dd7ec09ee65b2f448f3cd250 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Mon, 23 Jun 2014 12:26:07 -0700 Subject: [PATCH] Remove GOST support code from ssl/ Also remove related quirk, SSL_OP_CRYPTOPRO_TLSEXT_BUG. Glue code is left in for now. Change-Id: Ic09593dabf7da6ba3904fffe59f322a7c7cb74f4 --- ssl/s3_clnt.c | 22 -------- ssl/s3_lib.c | 12 ---- ssl/s3_srvr.c | 154 +++++++++----------------------------------------- ssl/ssl.h | 5 -- ssl/t1_lib.c | 15 ----- 5 files changed, 26 insertions(+), 182 deletions(-) diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index ee4f8659..f463f2f1 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -2898,28 +2898,6 @@ int ssl3_send_client_verify(SSL *s) } else #endif - if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) - { - unsigned char signbuf[64]; - int i, j; - size_t sigsize=64; - - s->method->ssl3_enc->cert_verify_mac(s, - NID_id_GostR3411_94, - data); - pctx = EVP_PKEY_CTX_new(pkey, NULL); - EVP_PKEY_sign_init(pctx); - if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_INTERNAL_ERROR); - goto err; - } - for (i=63,j=0; i>=0; j++, i--) { - p[2+j]=signbuf[i]; - } - s2n(j,p); - n=j+2; - } - else { OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_INTERNAL_ERROR); goto err; diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 92b36802..4a50d715 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3956,18 +3956,6 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) alg_k = s->s3->tmp.new_cipher->algorithm_mkey; -#ifndef OPENSSL_NO_GOST - if (s->version >= TLS1_VERSION) - { - if (alg_k & SSL_kGOST) - { - p[ret++]=TLS_CT_GOST94_SIGN; - p[ret++]=TLS_CT_GOST01_SIGN; - return(ret); - } - } -#endif - #ifndef OPENSSL_NO_DH if (alg_k & (SSL_kDHr|SSL_kEDH)) { diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 1fc10a34..81aff9df 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -585,9 +585,6 @@ int ssl3_accept(SSL *s) * the client sends its ECDH pub key in * a certificate, the CertificateVerify * message is not sent. - * Also for GOST ciphersuites when - * the client uses its key from the certificate - * for key exchange. */ s->init_num = 0; s->state=SSL3_ST_SR_POST_CLIENT_CERT; @@ -2679,77 +2676,10 @@ int ssl3_get_client_key_exchange(SSL *s) } #endif else if (alg_k & SSL_kGOST) - { - int ret = 0; - EVP_PKEY_CTX *pkey_ctx; - EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; - unsigned char premaster_secret[32], *start; - size_t outlen=32, inlen; - unsigned long alg_a; - - /* 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) - pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; - - pkey_ctx = EVP_PKEY_CTX_new(pk,NULL); - EVP_PKEY_decrypt_init(pkey_ctx); - /* If client certificate is present and is of the same type, maybe - * use it for key exchange. Don't mind errors from - * EVP_PKEY_derive_set_peer, because it is completely valid to use - * a client certificate for authorization only. */ - client_pub_pkey = X509_get_pubkey(s->session->peer); - if (client_pub_pkey) - { - if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) - ERR_clear_error(); - } - /* Decrypt session key */ - if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) - { - OPENSSL_PUT_ERROR(SSL, 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 - { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECRYPTION_FAILED); - goto gerr; - } - if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) - - { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECRYPTION_FAILED); - goto gerr; - } - /* Generate master secret */ - s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, - s->session->master_key,premaster_secret,32); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) - ret = 2; - else - ret = 1; - gerr: - EVP_PKEY_free(client_pub_pkey); - EVP_PKEY_CTX_free(pkey_ctx); - if (ret) - return ret; - else - goto err; - } + { + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_GOST_NOT_SUPPORTED); + goto err; + } else if (!(alg_k & SSL_kPSK)) { al=SSL_AD_HANDSHAKE_FAILURE; @@ -2842,44 +2772,33 @@ int ssl3_get_cert_verify(SSL *s) /* we now have a signature that we need to verify */ p=(unsigned char *)s->init_msg; - /* 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) ) + if (SSL_USE_SIGALGS(s)) { - i=64; - } - else - { - if (SSL_USE_SIGALGS(s)) + int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + if (rv == -1) { - int rv = tls12_check_peer_sigalg(&md, s, p, pkey); - if (rv == -1) - { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - else if (rv == 0) - { - al = SSL_AD_DECODE_ERROR; - goto f_err; - } + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + else if (rv == 0) + { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } #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) - { - OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_LENGTH_MISMATCH); - al=SSL_AD_DECODE_ERROR; - goto f_err; - } - } + p += 2; + n -= 2; + } + n2s(p,i); + n-=2; + if (i > n) + { + OPENSSL_PUT_ERROR(SSL, 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)) { @@ -2972,27 +2891,6 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); } else #endif - if (pkey->type == NID_id_GostR3410_94 || 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); - } - for (idx=0;idx<64;idx++) { - signature[63-idx]=p[idx]; - } - j=EVP_PKEY_verify(pctx,signature,64,s->s3->tmp.cert_verify_md,32); - EVP_PKEY_CTX_free(pctx); - if (j<=0) - { - al=SSL_AD_DECRYPT_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } - else { OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, ERR_R_INTERNAL_ERROR); al=SSL_AD_UNSUPPORTED_CERTIFICATE; diff --git a/ssl/ssl.h b/ssl/ssl.h index fdb28083..c35c7f50 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -683,11 +683,6 @@ struct ssl_session_st #define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L -/* Make server add server-hello extension from early version of - * cryptopro draft, when GOST ciphersuite is negotiated. - * Required for interoperability with CryptoPro CSP 3.x - */ -#define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L /* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success * when just a single record has been written): */ diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 08a70022..4107bad2 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1806,21 +1806,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c ret+=el; } - if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) - && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) - { const unsigned char cryptopro_ext[36] = { - 0xfd, 0xe8, /*65000*/ - 0x00, 0x20, /*32 bytes length*/ - 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, - 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, - 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, - 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17}; - if (limit-ret<36) return NULL; - memcpy(ret,cryptopro_ext,36); - ret+=36; - - } - #ifndef OPENSSL_NO_HEARTBEATS /* Add Heartbeat extension if we've received one */ if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)