perform sanity checks on server certificate type as soon as it is received instead of waiting until server key exchange
(backport from HEAD)
This commit is contained in:
parent
79dcae32ef
commit
67d9dcf003
@ -1225,6 +1225,15 @@ int ssl3_get_server_certificate(SSL *s)
|
|||||||
|
|
||||||
if (need_cert)
|
if (need_cert)
|
||||||
{
|
{
|
||||||
|
int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
|
||||||
|
if (exp_idx >= 0 && i != exp_idx)
|
||||||
|
{
|
||||||
|
x=NULL;
|
||||||
|
al=SSL_AD_ILLEGAL_PARAMETER;
|
||||||
|
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
|
||||||
|
SSL_R_WRONG_CERTIFICATE_TYPE);
|
||||||
|
goto f_err;
|
||||||
|
}
|
||||||
sc->peer_cert_type=i;
|
sc->peer_cert_type=i;
|
||||||
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
|
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
|
||||||
/* Why would the following ever happen?
|
/* Why would the following ever happen?
|
||||||
|
@ -2780,6 +2780,7 @@ void ERR_load_SSL_strings(void);
|
|||||||
#define SSL_R_UNSUPPORTED_STATUS_TYPE 329
|
#define SSL_R_UNSUPPORTED_STATUS_TYPE 329
|
||||||
#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369
|
#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369
|
||||||
#define SSL_R_WRITE_BIO_NOT_SET 260
|
#define SSL_R_WRITE_BIO_NOT_SET 260
|
||||||
|
#define SSL_R_WRONG_CERTIFICATE_TYPE 383
|
||||||
#define SSL_R_WRONG_CIPHER_RETURNED 261
|
#define SSL_R_WRONG_CIPHER_RETURNED 261
|
||||||
#define SSL_R_WRONG_CURVE 378
|
#define SSL_R_WRONG_CURVE 378
|
||||||
#define SSL_R_WRONG_MESSAGE_TYPE 262
|
#define SSL_R_WRONG_MESSAGE_TYPE 262
|
||||||
|
@ -1890,5 +1890,47 @@ const char *SSL_COMP_get_name(const COMP_METHOD *comp)
|
|||||||
return comp->name;
|
return comp->name;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
/* For a cipher return the index corresponding to the certificate type */
|
||||||
|
int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
|
||||||
|
{
|
||||||
|
unsigned long alg_k, alg_a;
|
||||||
|
|
||||||
|
alg_k = c->algorithm_mkey;
|
||||||
|
alg_a = c->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)
|
||||||
|
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;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -608,6 +608,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
|||||||
{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
|
{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
|
||||||
{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED),"use srtp not negotiated"},
|
{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED),"use srtp not negotiated"},
|
||||||
{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) ,"write bio not set"},
|
{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) ,"write bio not set"},
|
||||||
|
{ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE),"wrong certificate type"},
|
||||||
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
|
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
|
||||||
{ERR_REASON(SSL_R_WRONG_CURVE) ,"wrong curve"},
|
{ERR_REASON(SSL_R_WRONG_CURVE) ,"wrong curve"},
|
||||||
{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) ,"wrong message type"},
|
{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) ,"wrong message type"},
|
||||||
|
@ -2335,56 +2335,15 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* THIS NEEDS CLEANING UP */
|
|
||||||
static int ssl_get_server_cert_index(const SSL *s)
|
static int ssl_get_server_cert_index(const SSL *s)
|
||||||
{
|
{
|
||||||
unsigned long alg_k, alg_a;
|
int idx;
|
||||||
|
idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
|
||||||
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
|
if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509)
|
||||||
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
|
idx = SSL_PKEY_RSA_SIGN;
|
||||||
|
if (idx == -1)
|
||||||
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) */
|
|
||||||
{
|
|
||||||
SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX,ERR_R_INTERNAL_ERROR);
|
SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX,ERR_R_INTERNAL_ERROR);
|
||||||
return -1;
|
return idx;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
|
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
|
||||||
|
@ -921,7 +921,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
|
|||||||
void ssl_update_cache(SSL *s, int mode);
|
void ssl_update_cache(SSL *s, int mode);
|
||||||
int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
|
int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
|
||||||
const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
|
const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
|
||||||
int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);
|
int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);
|
||||||
|
int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
|
||||||
int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
|
int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
|
||||||
int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
|
int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
|
||||||
int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
|
int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user