X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=c3b40323687cd0ddbd733044b83319150f00c9a8;hp=bec87d81413650a10dc0c74afb0dc265964654b0;hb=8a97a33063d93be1130b762daefd729346af4d29;hpb=6dbb6219e7a6a5f94c9e7b0a25f0ce7c733f5060 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index bec87d8141..c3b4032368 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -263,7 +263,7 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth) sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list), &(ctx->cipher_list_by_id), - meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); + meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, ctx->cert); if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); @@ -1112,8 +1112,7 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) return 0; #endif - if (SSL_version(s) == DTLS1_VERSION || - SSL_version(s) == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { s->d1->mtu = larg; return larg; @@ -1132,6 +1131,17 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) return(s->cert->cert_flags|=larg); case SSL_CTRL_CLEAR_CERT_FLAGS: return(s->cert->cert_flags &=~larg); + + case SSL_CTRL_GET_RAW_CIPHERLIST: + if (parg) + { + if (s->cert->ciphers_raw == NULL) + return 0; + *(unsigned char **)parg = s->cert->ciphers_raw; + return (int)s->cert->ciphers_rawlen; + } + else + return ssl_put_cipher_by_char(s,NULL,NULL); default: return(s->method->ssl_ctrl(s,cmd,larg,parg)); } @@ -1158,6 +1168,20 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) { long l; + /* For some cases with ctx == NULL perform syntax checks */ + if (ctx == NULL) + { + switch (cmd) + { + case SSL_CTRL_SET_CURVES_LIST: + return tls1_set_curves_list(NULL, NULL, parg); + case SSL_CTRL_SET_SIGALGS_LIST: + case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: + return tls1_set_sigalgs_list(NULL, parg, 0); + default: + return 0; + } + } switch (cmd) { @@ -1333,7 +1357,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) STACK_OF(SSL_CIPHER) *sk; sk=ssl_create_cipher_list(ctx->method,&ctx->cipher_list, - &ctx->cipher_list_by_id,str); + &ctx->cipher_list_by_id,str, ctx->cert); /* ssl_create_cipher_list may return an empty stack if it * was unable to find a cipher matching the given rule string * (for example if the rule string specifies a cipher which @@ -1357,7 +1381,7 @@ int SSL_set_cipher_list(SSL *s,const char *str) STACK_OF(SSL_CIPHER) *sk; sk=ssl_create_cipher_list(s->ctx->method,&s->cipher_list, - &s->cipher_list_by_id,str); + &s->cipher_list_by_id,str, s->cert); /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; @@ -1412,6 +1436,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, SSL_CIPHER *c; CERT *ct = s->cert; unsigned char *q; + int no_scsv = s->renegotiate; /* Set disabled masks for this session */ ssl_set_client_disabled(s); @@ -1426,13 +1451,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) continue; +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (c->id == SSL3_CK_SCSV) + { + if (no_scsv) + continue; + else + no_scsv = 1; + } +#endif j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); p+=j; } /* If p == q, no ciphers and caller indicates an error. Otherwise * add SCSV if not renegotiating. */ - if (p != q && !s->renegotiate) + if (p != q && !no_scsv) { static SSL_CIPHER scsv = { @@ -1471,6 +1505,16 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, sk_SSL_CIPHER_zero(sk); } + if (s->cert->ciphers_raw) + OPENSSL_free(s->cert->ciphers_raw); + s->cert->ciphers_raw = BUF_memdup(p, num); + if (s->cert->ciphers_raw == NULL) + { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE); + goto err; + } + s->cert->ciphers_rawlen = (size_t)num; + for (i=0; imethod, &ret->cipher_list,&ret->cipher_list_by_id, - meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); + meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, ret->cert); if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { @@ -1821,7 +1865,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); ret->extra_certs=NULL; - ret->comp_methods=SSL_COMP_get_compression_methods(); + /* No compression for DTLS */ + if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) + ret->comp_methods=SSL_COMP_get_compression_methods(); ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; @@ -2336,59 +2382,18 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) #endif -/* THIS NEEDS CLEANING UP */ -static int ssl_get_server_cert_index(SSL *s) +static int ssl_get_server_cert_index(const SSL *s) { - unsigned long alg_k, alg_a; - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - if (alg_k & (SSL_kECDHr|SSL_kECDHe)) - { - /* we don't need to look at SSL_kEECDH - * since no certificate is needed for - * anon ECDH and for authenticated - * EECDH, the check for the auth - * algorithm will set i correctly - * NOTE: For ECDH-RSA, we need an ECC - * not an RSA cert but for EECDH-RSA - * we need an RSA cert. Placing the - * checks for SSL_kECDH before RSA - * checks ensures the correct cert is chosen. - */ - return SSL_PKEY_ECC; - } - else if (alg_a & SSL_aECDSA) - return SSL_PKEY_ECC; - else if (alg_k & SSL_kDHr) - return SSL_PKEY_DH_RSA; - else if (alg_k & SSL_kDHd) - return SSL_PKEY_DH_DSA; - else if (alg_a & SSL_aDSS) - return SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) - { - if (s->cert->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL) - return SSL_PKEY_RSA_SIGN; - else - return SSL_PKEY_RSA_ENC; - } - else if (alg_a & SSL_aKRB5) - /* VRS something else here? */ - return -1; - else if (alg_a & SSL_aGOST94) - return SSL_PKEY_GOST94; - else if (alg_a & SSL_aGOST01) - return SSL_PKEY_GOST01; - else /* if (alg_a & SSL_aNULL) */ - { + int idx; + idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); + if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) + idx = SSL_PKEY_RSA_SIGN; + if (idx == -1) SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX,ERR_R_INTERNAL_ERROR); - return -1; - } + return idx; } -CERT_PKEY *ssl_get_server_send_pkey(SSL *s) +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) { CERT *c; int i; @@ -2396,6 +2401,14 @@ CERT_PKEY *ssl_get_server_send_pkey(SSL *s) c = s->cert; ssl_set_cert_masks(c, s->s3->tmp.new_cipher); +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* Broken protocol test: return last used certificate: which may + * mismatch the one expected. + */ + if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + return c->key; +#endif + i = ssl_get_server_cert_index(s); /* This may or may not be an error. */ @@ -2415,6 +2428,15 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) alg_a = cipher->algorithm_auth; c=s->cert; +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* Broken protocol test: use last key: which may + * mismatch the one expected. + */ + if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + idx = c->key - c->pkeys; + else +#endif + if ((alg_a & SSL_aDSS) && (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) idx = SSL_PKEY_DSA_SIGN;