Security framework.
Security callback: selects which parameters are permitted including sensible defaults based on bits of security. The "parameters" which can be selected include: ciphersuites, curves, key sizes, certificate signature algorithms, supported signature algorithms, DH parameters, SSL/TLS version, session tickets and compression. In some cases prohibiting the use of a parameters will mean they are not advertised to the peer: for example cipher suites and ECC curves. In other cases it will abort the handshake: e.g DH parameters or the peer key size. Documentation to follow...
This commit is contained in:
parent
66f96fe2d5
commit
b362ccab5c
@ -259,10 +259,13 @@ static int ssl23_no_ssl2_ciphers(SSL *s)
|
||||
SSL_CIPHER *cipher;
|
||||
STACK_OF(SSL_CIPHER) *ciphers;
|
||||
int i;
|
||||
ssl_set_client_disabled(s);
|
||||
ciphers = SSL_get_ciphers(s);
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
|
||||
{
|
||||
cipher = sk_SSL_CIPHER_value(ciphers, i);
|
||||
if (ssl_cipher_disabled(s, cipher, SSL_SECOP_CIPHER_SUPPORTED))
|
||||
continue;
|
||||
if (cipher->algorithm_ssl == SSL_SSLV2)
|
||||
return 0;
|
||||
}
|
||||
@ -309,6 +312,8 @@ static int ssl23_client_hello(SSL *s)
|
||||
|
||||
ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1;
|
||||
|
||||
if (ssl2_compat && !ssl_security(s, SSL_SECOP_SSL2_COMPAT, 0, 0, NULL))
|
||||
ssl2_compat = 0;
|
||||
if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
|
||||
ssl2_compat = 0;
|
||||
|
||||
@ -533,8 +538,7 @@ static int ssl23_client_hello(SSL *s)
|
||||
#ifdef OPENSSL_NO_COMP
|
||||
*(p++)=1;
|
||||
#else
|
||||
if ((s->options & SSL_OP_NO_COMPRESSION)
|
||||
|| !s->ctx->comp_methods)
|
||||
if (!ssl_allow_compression(s) || !s->ctx->comp_methods)
|
||||
j=0;
|
||||
else
|
||||
j=sk_SSL_COMP_num(s->ctx->comp_methods);
|
||||
@ -750,6 +754,12 @@ static int ssl23_get_server_hello(SSL *s)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_VERSION_TOO_LOW);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
|
||||
{
|
||||
/* fatal alert */
|
||||
|
@ -441,6 +441,12 @@ int ssl23_get_client_hello(SSL *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_VERSION_TOO_LOW);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
|
||||
{
|
||||
/* we have SSLv3/TLSv1 in an SSLv2 header
|
||||
|
@ -1056,6 +1056,12 @@ int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
|
||||
ERR_clear_error(); /* but we keep s->verify_result */
|
||||
s->session->verify_result = s->verify_result;
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL2_SET_CERTIFICATE, i);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* server's cert for this session */
|
||||
sc=ssl_sess_cert_new();
|
||||
if (sc == NULL)
|
||||
|
@ -1053,6 +1053,12 @@ static int request_certificate(SSL *s)
|
||||
|
||||
i=ssl_verify_cert_chain(s,sk);
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
SSLerr(SSL_F_REQUEST_CERTIFICATE, i);
|
||||
goto msg_end;
|
||||
}
|
||||
|
||||
if (i > 0) /* we like the packet, now check the chksum */
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
|
@ -695,7 +695,7 @@ int ssl3_setup_read_buffer(SSL *s)
|
||||
len += SSL3_RT_MAX_EXTRA;
|
||||
}
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (!(s->options & SSL_OP_NO_COMPRESSION))
|
||||
if (ssl_allow_compression(s))
|
||||
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
#endif
|
||||
if ((p=freelist_extract(s->ctx, 1, len)) == NULL)
|
||||
@ -732,7 +732,7 @@ int ssl3_setup_write_buffer(SSL *s)
|
||||
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
|
||||
+ headerlen + align;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (!(s->options & SSL_OP_NO_COMPRESSION))
|
||||
if (ssl_allow_compression(s))
|
||||
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
#endif
|
||||
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
|
||||
@ -782,3 +782,10 @@ int ssl3_release_read_buffer(SSL *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_allow_compression(SSL *s)
|
||||
{
|
||||
if (s->options & SSL_OP_NO_COMPRESSION)
|
||||
return 0;
|
||||
return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL);
|
||||
}
|
||||
|
||||
|
@ -240,6 +240,13 @@ int ssl3_connect(SSL *s)
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!ssl_security(s, SSL_SECOP_VERSION, 0,
|
||||
s->version, NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CONNECT, SSL_R_VERSION_TOO_LOW);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* s->version=SSL3_VERSION; */
|
||||
s->type=SSL_ST_CONNECT;
|
||||
@ -871,8 +878,7 @@ int ssl3_client_hello(SSL *s)
|
||||
*(p++)=1;
|
||||
#else
|
||||
|
||||
if ((s->options & SSL_OP_NO_COMPRESSION)
|
||||
|| !s->ctx->comp_methods)
|
||||
if (!ssl_allow_compression(s) || !s->ctx->comp_methods)
|
||||
j=0;
|
||||
else
|
||||
j=sk_SSL_COMP_num(s->ctx->comp_methods);
|
||||
@ -1079,7 +1085,7 @@ int ssl3_get_server_hello(SSL *s)
|
||||
/* If it is a disabled cipher we didn't send it in client hello,
|
||||
* so return an error.
|
||||
*/
|
||||
if (ssl_cipher_disabled(s, c))
|
||||
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK))
|
||||
{
|
||||
al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
|
||||
@ -1148,7 +1154,7 @@ int ssl3_get_server_hello(SSL *s)
|
||||
}
|
||||
if (j == 0)
|
||||
comp=NULL;
|
||||
else if (s->options & SSL_OP_NO_COMPRESSION)
|
||||
else if (!ssl_allow_compression(s))
|
||||
{
|
||||
al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED);
|
||||
@ -1290,6 +1296,12 @@ int ssl3_get_server_certificate(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
ERR_clear_error(); /* but we keep s->verify_result */
|
||||
if (i > 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, i);
|
||||
al = SSL_AD_HANDSHAKE_FAILURE;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
sc=ssl_sess_cert_new();
|
||||
if (sc == NULL) goto err;
|
||||
@ -1709,6 +1721,14 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
p+=i;
|
||||
n-=param_len;
|
||||
|
||||
if (!ssl_security(s, SSL_SECOP_TMP_DH,
|
||||
DH_security_bits(dh), 0, dh))
|
||||
{
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_DH_KEY_TOO_SMALL);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_a & SSL_aRSA)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
|
80
ssl/s3_lib.c
80
ssl/s3_lib.c
@ -3228,6 +3228,12 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return(ret);
|
||||
}
|
||||
if (!ssl_security(s, SSL_SECOP_TMP_DH,
|
||||
DH_security_bits(dh), 0, dh))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTRL, SSL_R_DH_KEY_TOO_SMALL);
|
||||
return(ret);
|
||||
}
|
||||
if ((dh = DHparams_dup(dh)) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
|
||||
@ -3415,17 +3421,17 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
|
||||
case SSL_CTRL_CHAIN:
|
||||
if (larg)
|
||||
return ssl_cert_set1_chain(s->cert,
|
||||
return ssl_cert_set1_chain(s, NULL,
|
||||
(STACK_OF (X509) *)parg);
|
||||
else
|
||||
return ssl_cert_set0_chain(s->cert,
|
||||
return ssl_cert_set0_chain(s, NULL,
|
||||
(STACK_OF (X509) *)parg);
|
||||
|
||||
case SSL_CTRL_CHAIN_CERT:
|
||||
if (larg)
|
||||
return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg);
|
||||
return ssl_cert_add1_chain_cert(s, NULL, (X509 *)parg);
|
||||
else
|
||||
return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg);
|
||||
return ssl_cert_add0_chain_cert(s, NULL, (X509 *)parg);
|
||||
|
||||
case SSL_CTRL_GET_CHAIN_CERTS:
|
||||
*(STACK_OF(X509) **)parg = s->cert->key->chain;
|
||||
@ -3533,7 +3539,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
return ssl3_set_req_cert_type(s->cert, parg, larg);
|
||||
|
||||
case SSL_CTRL_BUILD_CERT_CHAIN:
|
||||
return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg);
|
||||
return ssl_build_cert_chain(s, NULL, larg);
|
||||
|
||||
case SSL_CTRL_SET_VERIFY_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(s->cert, parg, 0, larg);
|
||||
@ -3736,6 +3742,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
DH *new=NULL,*dh;
|
||||
|
||||
dh=(DH *)parg;
|
||||
if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
|
||||
DH_security_bits(dh), 0, dh))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_DH_KEY_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
if ((new=DHparams_dup(dh)) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_DH_LIB);
|
||||
@ -3911,7 +3923,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
return ssl3_set_req_cert_type(ctx->cert, parg, larg);
|
||||
|
||||
case SSL_CTRL_BUILD_CERT_CHAIN:
|
||||
return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg);
|
||||
return ssl_build_cert_chain(NULL, ctx, larg);
|
||||
|
||||
case SSL_CTRL_SET_VERIFY_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg);
|
||||
@ -3948,17 +3960,17 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
|
||||
case SSL_CTRL_CHAIN:
|
||||
if (larg)
|
||||
return ssl_cert_set1_chain(ctx->cert,
|
||||
return ssl_cert_set1_chain(NULL, ctx,
|
||||
(STACK_OF (X509) *)parg);
|
||||
else
|
||||
return ssl_cert_set0_chain(ctx->cert,
|
||||
return ssl_cert_set0_chain(NULL, ctx,
|
||||
(STACK_OF (X509) *)parg);
|
||||
|
||||
case SSL_CTRL_CHAIN_CERT:
|
||||
if (larg)
|
||||
return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg);
|
||||
return ssl_cert_add1_chain_cert(NULL, ctx, (X509 *)parg);
|
||||
else
|
||||
return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg);
|
||||
return ssl_cert_add0_chain_cert(NULL, ctx, (X509 *)parg);
|
||||
|
||||
case SSL_CTRL_GET_CHAIN_CERTS:
|
||||
*(STACK_OF(X509) **)parg = ctx->cert->key->chain;
|
||||
@ -4203,6 +4215,10 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
ii=sk_SSL_CIPHER_find(allow,c);
|
||||
if (ii >= 0)
|
||||
{
|
||||
/* Check security callback permits this cipher */
|
||||
if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED,
|
||||
c->strength_bits, 0, c))
|
||||
continue;
|
||||
#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT)
|
||||
if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA) && s->s3->is_probably_safari)
|
||||
{
|
||||
@ -4220,14 +4236,8 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
|
||||
{
|
||||
int ret=0;
|
||||
const unsigned char *sig;
|
||||
size_t i, siglen;
|
||||
int have_rsa_sign = 0, have_dsa_sign = 0;
|
||||
#ifndef OPENSSL_NO_ECDSA
|
||||
int have_ecdsa_sign = 0;
|
||||
#endif
|
||||
int nostrict = 1;
|
||||
unsigned long alg_k;
|
||||
unsigned long alg_k, alg_a = 0;
|
||||
|
||||
/* If we have custom certificate types set, use them */
|
||||
if (s->cert->ctypes)
|
||||
@ -4235,28 +4245,10 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
|
||||
memcpy(p, s->cert->ctypes, s->cert->ctype_num);
|
||||
return (int)s->cert->ctype_num;
|
||||
}
|
||||
/* get configured sigalgs */
|
||||
siglen = tls12_get_psigalgs(s, &sig);
|
||||
/* Get mask of algorithms disabled by signature list */
|
||||
ssl_set_sig_mask(&alg_a, s, SSL_SECOP_SIGALG_MASK);
|
||||
if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
|
||||
nostrict = 0;
|
||||
for (i = 0; i < siglen; i+=2, sig+=2)
|
||||
{
|
||||
switch(sig[1])
|
||||
{
|
||||
case TLSEXT_signature_rsa:
|
||||
have_rsa_sign = 1;
|
||||
break;
|
||||
|
||||
case TLSEXT_signature_dsa:
|
||||
have_dsa_sign = 1;
|
||||
break;
|
||||
#ifndef OPENSSL_NO_ECDSA
|
||||
case TLSEXT_signature_ecdsa:
|
||||
have_ecdsa_sign = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
|
||||
|
||||
@ -4279,11 +4271,11 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
|
||||
/* Since this refers to a certificate signed with an RSA
|
||||
* algorithm, only check for rsa signing in strict mode.
|
||||
*/
|
||||
if (nostrict || have_rsa_sign)
|
||||
if (nostrict || !(alg_a & SSL_aRSA))
|
||||
p[ret++]=SSL3_CT_RSA_FIXED_DH;
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
if (nostrict || have_dsa_sign)
|
||||
if (nostrict || !(alg_a & SSL_aDSS))
|
||||
p[ret++]=SSL3_CT_DSS_FIXED_DH;
|
||||
# endif
|
||||
}
|
||||
@ -4299,19 +4291,19 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
|
||||
}
|
||||
#endif /* !OPENSSL_NO_DH */
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (have_rsa_sign)
|
||||
if (!(alg_a & SSL_aRSA))
|
||||
p[ret++]=SSL3_CT_RSA_SIGN;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
if (have_dsa_sign)
|
||||
if (!(alg_a & SSL_aDSS))
|
||||
p[ret++]=SSL3_CT_DSS_SIGN;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION))
|
||||
{
|
||||
if (nostrict || have_rsa_sign)
|
||||
if (nostrict || !(alg_a & SSL_aRSA))
|
||||
p[ret++]=TLS_CT_RSA_FIXED_ECDH;
|
||||
if (nostrict || have_ecdsa_sign)
|
||||
if (nostrict || !(alg_a & SSL_aECDSA))
|
||||
p[ret++]=TLS_CT_ECDSA_FIXED_ECDH;
|
||||
}
|
||||
#endif
|
||||
@ -4322,7 +4314,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
|
||||
*/
|
||||
if (s->version >= TLS1_VERSION)
|
||||
{
|
||||
if (have_ecdsa_sign)
|
||||
if (!(alg_a & SSL_aECDSA))
|
||||
p[ret++]=TLS_CT_ECDSA_SIGN;
|
||||
}
|
||||
#endif
|
||||
|
@ -272,6 +272,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)
|
||||
@ -1305,7 +1313,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;
|
||||
@ -1340,7 +1348,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;
|
||||
|
||||
@ -1701,7 +1709,13 @@ 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);
|
||||
@ -2115,9 +2129,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;
|
||||
}
|
||||
@ -3413,6 +3431,7 @@ int ssl3_get_client_certificate(SSL *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
i=ssl_verify_cert_chain(s,sk);
|
||||
if (i <= 0)
|
||||
{
|
||||
@ -3420,6 +3439,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 */
|
||||
|
82
ssl/ssl.h
82
ssl/ssl.h
@ -2573,6 +2573,80 @@ void SSL_trace(int write_p, int version, int content_type,
|
||||
const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
|
||||
#endif
|
||||
|
||||
/* What the "other" parameter contains in security callback */
|
||||
/* Mask for type */
|
||||
#define SSL_SECOP_OTHER_TYPE 0xffff0000
|
||||
#define SSL_SECOP_OTHER_NONE 0
|
||||
#define SSL_SECOP_OTHER_CIPHER (1 << 16)
|
||||
#define SSL_SECOP_OTHER_CURVE (2 << 16)
|
||||
#define SSL_SECOP_OTHER_DH (3 << 16)
|
||||
#define SSL_SECOP_OTHER_PKEY (4 << 16)
|
||||
#define SSL_SECOP_OTHER_SIGALG (5 << 16)
|
||||
#define SSL_SECOP_OTHER_CERT (6 << 16)
|
||||
|
||||
/* Indicated operation refers to peer key or certificate */
|
||||
#define SSL_SECOP_PEER 0x1000
|
||||
|
||||
/* Values for "op" parameter in security callback */
|
||||
|
||||
/* Called to filter ciphers */
|
||||
/* Ciphers client supports */
|
||||
#define SSL_SECOP_CIPHER_SUPPORTED (1 | SSL_SECOP_OTHER_CIPHER)
|
||||
/* Cipher shared by client/server */
|
||||
#define SSL_SECOP_CIPHER_SHARED (2 | SSL_SECOP_OTHER_CIPHER)
|
||||
/* Sanity check of cipher server selects */
|
||||
#define SSL_SECOP_CIPHER_CHECK (3 | SSL_SECOP_OTHER_CIPHER)
|
||||
/* Curves supported by client */
|
||||
#define SSL_SECOP_CURVE_SUPPORTED (4 | SSL_SECOP_OTHER_CURVE)
|
||||
/* Curves shared by client/server */
|
||||
#define SSL_SECOP_CURVE_SHARED (5 | SSL_SECOP_OTHER_CURVE)
|
||||
/* Sanity check of curve server selects */
|
||||
#define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE)
|
||||
/* Temporary DH key */
|
||||
#define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_DH)
|
||||
/* Whether to use SSLv2 compatible client hello */
|
||||
#define SSL_SECOP_SSL2_COMPAT (8 | SSL_SECOP_OTHER_NONE)
|
||||
/* SSL/TLS version */
|
||||
#define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE)
|
||||
/* Session tickets */
|
||||
#define SSL_SECOP_TICKET (10 | SSL_SECOP_OTHER_NONE)
|
||||
/* Supported signature algorithms sent to peer */
|
||||
#define SSL_SECOP_SIGALG_SUPPORTED (11 | SSL_SECOP_OTHER_SIGALG)
|
||||
/* Shared signature algorithm */
|
||||
#define SSL_SECOP_SIGALG_SHARED (12 | SSL_SECOP_OTHER_SIGALG)
|
||||
/* Sanity check signature algorithm allowed */
|
||||
#define SSL_SECOP_SIGALG_CHECK (13 | SSL_SECOP_OTHER_SIGALG)
|
||||
/* Used to get mask of supported public key signature algorithms */
|
||||
#define SSL_SECOP_SIGALG_MASK (14 | SSL_SECOP_OTHER_SIGALG)
|
||||
/* Use to see if compression is allowed */
|
||||
#define SSL_SECOP_COMPRESSION (15 | SSL_SECOP_OTHER_NONE)
|
||||
/* EE key in certificate */
|
||||
#define SSL_SECOP_EE_KEY (16 | SSL_SECOP_OTHER_CERT)
|
||||
/* CA key in certificate */
|
||||
#define SSL_SECOP_CA_KEY (17 | SSL_SECOP_OTHER_CERT)
|
||||
/* CA digest algorithm in certificate */
|
||||
#define SSL_SECOP_CA_MD (18 | SSL_SECOP_OTHER_CERT)
|
||||
/* Peer EE key in certificate */
|
||||
#define SSL_SECOP_PEER_EE_KEY (SSL_SECOP_EE_KEY | SSL_SECOP_PEER)
|
||||
/* Peer CA key in certificate */
|
||||
#define SSL_SECOP_PEER_CA_KEY (SSL_SECOP_CA_KEY | SSL_SECOP_PEER)
|
||||
/* Peer CA digest algorithm in certificate */
|
||||
#define SSL_SECOP_PEER_CA_MD (SSL_SECOP_CA_MD | SSL_SECOP_PEER)
|
||||
|
||||
void SSL_set_security_level(SSL *s, int level);
|
||||
int SSL_get_security_level(const SSL *s);
|
||||
void SSL_set_security_callback(SSL *s, int (*cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex));
|
||||
int (*SSL_get_security_callback(const SSL *s))(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex);
|
||||
void SSL_set0_security_ex_data(SSL *s, void *ex);
|
||||
void *SSL_get0_security_ex_data(const SSL *s);
|
||||
|
||||
void SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
|
||||
int SSL_CTX_get_security_level(const SSL_CTX *ctx);
|
||||
void SSL_CTX_set_security_callback(SSL_CTX *ctx, int (*cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex));
|
||||
int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx))(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex);
|
||||
void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex);
|
||||
void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx);
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@ -2710,10 +2784,12 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_BAD_METHOD 160
|
||||
#define SSL_F_SSL_BUILD_CERT_CHAIN 332
|
||||
#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161
|
||||
#define SSL_F_SSL_CERT_ADD0_CHAIN_CERT 339
|
||||
#define SSL_F_SSL_CERT_DUP 221
|
||||
#define SSL_F_SSL_CERT_INST 222
|
||||
#define SSL_F_SSL_CERT_INSTANTIATE 214
|
||||
#define SSL_F_SSL_CERT_NEW 162
|
||||
#define SSL_F_SSL_CERT_SET0_CHAIN 340
|
||||
#define SSL_F_SSL_CHECK_PRIVATE_KEY 163
|
||||
#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280
|
||||
#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279
|
||||
@ -2874,6 +2950,8 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_BN_LIB 130
|
||||
#define SSL_R_CA_DN_LENGTH_MISMATCH 131
|
||||
#define SSL_R_CA_DN_TOO_LONG 132
|
||||
#define SSL_R_CA_KEY_TOO_SMALL 397
|
||||
#define SSL_R_CA_MD_TOO_WEAK 398
|
||||
#define SSL_R_CCS_RECEIVED_EARLY 133
|
||||
#define SSL_R_CERTIFICATE_VERIFY_FAILED 134
|
||||
#define SSL_R_CERT_CB_ERROR 377
|
||||
@ -2895,6 +2973,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_DATA_LENGTH_TOO_LONG 146
|
||||
#define SSL_R_DECRYPTION_FAILED 147
|
||||
#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281
|
||||
#define SSL_R_DH_KEY_TOO_SMALL 394
|
||||
#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148
|
||||
#define SSL_R_DIGEST_CHECK_FAILED 149
|
||||
#define SSL_R_DTLS_MESSAGE_TOO_BIG 334
|
||||
@ -2904,6 +2983,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322
|
||||
#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323
|
||||
#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310
|
||||
#define SSL_R_EE_KEY_TOO_SMALL 399
|
||||
#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354
|
||||
#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
|
||||
#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282
|
||||
@ -2931,6 +3011,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325
|
||||
#define SSL_R_INVALID_TRUST 279
|
||||
#define SSL_R_KEY_ARG_TOO_LONG 284
|
||||
#define SSL_R_KEY_TOO_SMALL 395
|
||||
#define SSL_R_KRB5 285
|
||||
#define SSL_R_KRB5_C_CC_PRINC 286
|
||||
#define SSL_R_KRB5_C_GET_CRED 287
|
||||
@ -3132,6 +3213,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_UNSUPPORTED_SSL_VERSION 259
|
||||
#define SSL_R_UNSUPPORTED_STATUS_TYPE 329
|
||||
#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369
|
||||
#define SSL_R_VERSION_TOO_LOW 396
|
||||
#define SSL_R_WRITE_BIO_NOT_SET 260
|
||||
#define SSL_R_WRONG_CERTIFICATE_TYPE 383
|
||||
#define SSL_R_WRONG_CIPHER_RETURNED 261
|
||||
|
175
ssl/ssl_cert.c
175
ssl/ssl_cert.c
@ -132,6 +132,8 @@
|
||||
#include <openssl/bn.h>
|
||||
#include "ssl_locl.h"
|
||||
|
||||
static int ssl_security_default_callback(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex);
|
||||
|
||||
int SSL_get_ex_data_X509_STORE_CTX_idx(void)
|
||||
{
|
||||
static volatile int ssl_x509_store_ctx_idx= -1;
|
||||
@ -190,6 +192,9 @@ CERT *ssl_cert_new(void)
|
||||
ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
|
||||
ret->references=1;
|
||||
ssl_cert_set_default_md(ret);
|
||||
ret->sec_cb = ssl_security_default_callback;
|
||||
ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL;
|
||||
ret->sec_ex = NULL;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@ -414,6 +419,10 @@ CERT *ssl_cert_dup(CERT *cert)
|
||||
|
||||
ret->ciphers_raw = NULL;
|
||||
|
||||
ret->sec_cb = cert->sec_cb;
|
||||
ret->sec_level = cert->sec_level;
|
||||
ret->sec_ex = cert->sec_ex;
|
||||
|
||||
return(ret);
|
||||
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
|
||||
@ -553,26 +562,36 @@ int ssl_cert_inst(CERT **o)
|
||||
return(1);
|
||||
}
|
||||
|
||||
int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
|
||||
int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
|
||||
{
|
||||
CERT_PKEY *cpk = c->key;
|
||||
int i, r;
|
||||
CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
|
||||
if (!cpk)
|
||||
return 0;
|
||||
if (cpk->chain)
|
||||
sk_X509_pop_free(cpk->chain, X509_free);
|
||||
for (i = 0; i < sk_X509_num(chain); i++)
|
||||
{
|
||||
r = ssl_security_cert(s, ctx, sk_X509_value(chain, i), 0, 0);
|
||||
if (r != 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CERT_SET0_CHAIN, r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cpk->chain = chain;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
|
||||
int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
|
||||
{
|
||||
STACK_OF(X509) *dchain;
|
||||
if (!chain)
|
||||
return ssl_cert_set0_chain(c, NULL);
|
||||
return ssl_cert_set0_chain(s, ctx, NULL);
|
||||
dchain = X509_chain_up_ref(chain);
|
||||
if (!dchain)
|
||||
return 0;
|
||||
if (!ssl_cert_set0_chain(c, dchain))
|
||||
if (!ssl_cert_set0_chain(s, ctx, dchain))
|
||||
{
|
||||
sk_X509_pop_free(dchain, X509_free);
|
||||
return 0;
|
||||
@ -580,11 +599,18 @@ int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_cert_add0_chain_cert(CERT *c, X509 *x)
|
||||
int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
CERT_PKEY *cpk = c->key;
|
||||
int r;
|
||||
CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
|
||||
if (!cpk)
|
||||
return 0;
|
||||
r = ssl_security_cert(s, ctx, x, 0, 0);
|
||||
if (r != 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CERT_ADD0_CHAIN_CERT, r);
|
||||
return 0;
|
||||
}
|
||||
if (!cpk->chain)
|
||||
cpk->chain = sk_X509_new_null();
|
||||
if (!cpk->chain || !sk_X509_push(cpk->chain, x))
|
||||
@ -592,9 +618,9 @@ int ssl_cert_add0_chain_cert(CERT *c, X509 *x)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_cert_add1_chain_cert(CERT *c, X509 *x)
|
||||
int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
if (!ssl_cert_add0_chain_cert(c, x))
|
||||
if (!ssl_cert_add0_chain_cert(s, ctx, x))
|
||||
return 0;
|
||||
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
|
||||
return 1;
|
||||
@ -790,6 +816,14 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
|
||||
{
|
||||
#ifndef OPENSSL_NO_X509_VERIFY
|
||||
i=X509_verify_cert(&ctx);
|
||||
#if 0
|
||||
/* Dummy error calls so mkerr generates them */
|
||||
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_EE_KEY_TOO_SMALL);
|
||||
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_CA_KEY_TOO_SMALL);
|
||||
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_CA_MD_TOO_WEAK);
|
||||
#endif
|
||||
if (i > 0)
|
||||
i = ssl_security_cert_chain(s, ctx.chain, NULL, 1);
|
||||
#else
|
||||
i=0;
|
||||
ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
|
||||
@ -1159,6 +1193,13 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
|
||||
X509_verify_cert(&xs_ctx);
|
||||
/* Don't leave errors in the queue */
|
||||
ERR_clear_error();
|
||||
i = ssl_security_cert_chain(s, xs_ctx.chain, NULL, 0);
|
||||
if (i != 1)
|
||||
{
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, i);
|
||||
return 0;
|
||||
}
|
||||
for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
|
||||
{
|
||||
x = sk_X509_value(xs_ctx.chain, i);
|
||||
@ -1173,6 +1214,12 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
|
||||
}
|
||||
else
|
||||
{
|
||||
i = ssl_security_cert_chain(s, extra_certs, x, 0);
|
||||
if (i != 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, i);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_add_cert_to_buf(buf, l, x))
|
||||
return 0;
|
||||
for (i=0; i<sk_X509_num(extra_certs); i++)
|
||||
@ -1186,9 +1233,11 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
|
||||
}
|
||||
|
||||
/* Build a certificate chain for current certificate */
|
||||
int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
|
||||
int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags)
|
||||
{
|
||||
CERT *c = s ? s->cert : ctx->cert;
|
||||
CERT_PKEY *cpk = c->key;
|
||||
X509_STORE *chain_store = NULL;
|
||||
X509_STORE_CTX xs_ctx;
|
||||
STACK_OF(X509) *chain = NULL, *untrusted = NULL;
|
||||
X509 *x;
|
||||
@ -1232,6 +1281,10 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
|
||||
{
|
||||
if (c->chain_store)
|
||||
chain_store = c->chain_store;
|
||||
else if (s)
|
||||
chain_store = s->ctx->cert_store;
|
||||
else
|
||||
chain_store = ctx->cert_store;
|
||||
|
||||
if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
|
||||
untrusted = cpk->chain;
|
||||
@ -1266,8 +1319,6 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
|
||||
goto err;
|
||||
}
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
if (cpk->chain)
|
||||
sk_X509_pop_free(cpk->chain, X509_free);
|
||||
/* Remove EE certificate from chain */
|
||||
x = sk_X509_shift(chain);
|
||||
X509_free(x);
|
||||
@ -1285,6 +1336,23 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check security level of all CA certificates: EE will have been
|
||||
* checked already.
|
||||
*/
|
||||
for (i = 0; i < sk_X509_num(chain); i++)
|
||||
{
|
||||
x = sk_X509_value(chain, i);
|
||||
rv = ssl_security_cert(s, ctx, x, 0, 0);
|
||||
if (rv != 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, rv);
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
rv = 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (cpk->chain)
|
||||
sk_X509_pop_free(cpk->chain, X509_free);
|
||||
cpk->chain = chain;
|
||||
if (rv == 0)
|
||||
rv = 1;
|
||||
@ -1310,3 +1378,86 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ssl_security_default_callback(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex)
|
||||
{
|
||||
int level, minbits;
|
||||
static const int minbits_table[5] = {80, 112, 128, 192, 256};
|
||||
if (ctx)
|
||||
level = SSL_CTX_get_security_level(ctx);
|
||||
else
|
||||
level = SSL_get_security_level(s);
|
||||
/* Level 0: anything goes */
|
||||
if (level <= 0)
|
||||
return 1;
|
||||
if (level > 5)
|
||||
level = 5;
|
||||
minbits = minbits_table[level - 1];
|
||||
switch (op)
|
||||
{
|
||||
case SSL_SECOP_CIPHER_SUPPORTED:
|
||||
case SSL_SECOP_CIPHER_SHARED:
|
||||
case SSL_SECOP_CIPHER_CHECK:
|
||||
{
|
||||
const SSL_CIPHER *c = other;
|
||||
/* No ciphers below security level */
|
||||
if (bits < minbits)
|
||||
return 0;
|
||||
/* No SSLv2 ciphers */
|
||||
if ((SSL_CIPHER_get_id(c) >> 24) == 0x2)
|
||||
return 0;
|
||||
/* No unauthenticated ciphersuites */
|
||||
if (c->algorithm_auth & SSL_aNULL)
|
||||
return 0;
|
||||
/* No MD5 mac ciphersuites */
|
||||
if (c->algorithm_mac & SSL_MD5)
|
||||
return 0;
|
||||
/* Level 2: no RC4 */
|
||||
if (level >= 2 && c->algorithm_enc == SSL_RC4)
|
||||
return 0;
|
||||
/* Level 3: forward secure ciphersuites only */
|
||||
if (level >= 3 && !(c->algorithm_mkey & (SSL_kEDH|SSL_kEECDH)))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SSL_SECOP_VERSION:
|
||||
/* SSLv2 allowed only on level zero */
|
||||
if (nid == SSL2_VERSION)
|
||||
return 0;
|
||||
/* SSLv3 not allowed on level 2 */
|
||||
if (nid <= SSL3_VERSION && level >= 2)
|
||||
return 0;
|
||||
/* TLS v1.1 and above only for level 3 */
|
||||
if (nid <= TLS1_VERSION && level >= 3)
|
||||
return 0;
|
||||
/* TLS v1.2 only for level 4 and above */
|
||||
if (nid <= TLS1_1_VERSION && level >= 4)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SSL_SECOP_COMPRESSION:
|
||||
if (level >= 2)
|
||||
return 0;
|
||||
break;
|
||||
case SSL_SECOP_TICKET:
|
||||
if (level >= 3)
|
||||
return 0;
|
||||
break;
|
||||
case SSL_SECOP_SSL2_COMPAT:
|
||||
/* SSLv2 compatible client hello only for level zero */
|
||||
return 0;
|
||||
default:
|
||||
if (bits < minbits)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_security(SSL *s, int op, int bits, int nid, void *other)
|
||||
{
|
||||
return s->cert->sec_cb(s, NULL, op, bits, nid, other, s->cert->sec_ex);
|
||||
}
|
||||
|
||||
int ssl_ctx_security(SSL_CTX *ctx, int op, int bits, int nid, void *other)
|
||||
{
|
||||
return ctx->cert->sec_cb(NULL, ctx, op, bits, nid, other, ctx->cert->sec_ex);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ssl/ssl_err.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -198,10 +198,12 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_BAD_METHOD), "ssl_bad_method"},
|
||||
{ERR_FUNC(SSL_F_SSL_BUILD_CERT_CHAIN), "ssl_build_cert_chain"},
|
||||
{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "ssl_bytes_to_cipher_list"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_ADD0_CHAIN_CERT), "ssl_cert_add0_chain_cert"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_DUP), "ssl_cert_dup"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_NEW), "ssl_cert_new"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_SET0_CHAIN), "ssl_cert_set0_chain"},
|
||||
{ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"},
|
||||
{ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), "SSL_CHECK_SERVERHELLO_TLSEXT"},
|
||||
{ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), "ssl_check_srvr_ecc_cert_and_alg"},
|
||||
@ -365,6 +367,8 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_BN_LIB) ,"bn lib"},
|
||||
{ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) ,"ca dn length mismatch"},
|
||||
{ERR_REASON(SSL_R_CA_DN_TOO_LONG) ,"ca dn too long"},
|
||||
{ERR_REASON(SSL_R_CA_KEY_TOO_SMALL) ,"ca key too small"},
|
||||
{ERR_REASON(SSL_R_CA_MD_TOO_WEAK) ,"ca md too weak"},
|
||||
{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) ,"ccs received early"},
|
||||
{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
|
||||
{ERR_REASON(SSL_R_CERT_CB_ERROR) ,"cert cb error"},
|
||||
@ -386,6 +390,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"},
|
||||
{ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"},
|
||||
{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
|
||||
{ERR_REASON(SSL_R_DH_KEY_TOO_SMALL) ,"dh key too small"},
|
||||
{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
|
||||
{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"},
|
||||
{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"},
|
||||
@ -395,6 +400,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"},
|
||||
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"},
|
||||
{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
|
||||
{ERR_REASON(SSL_R_EE_KEY_TOO_SMALL) ,"ee key too small"},
|
||||
{ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST),"empty srtp protection profile list"},
|
||||
{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
|
||||
{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
|
||||
@ -422,6 +428,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
|
||||
{ERR_REASON(SSL_R_INVALID_TRUST) ,"invalid trust"},
|
||||
{ERR_REASON(SSL_R_KEY_ARG_TOO_LONG) ,"key arg too long"},
|
||||
{ERR_REASON(SSL_R_KEY_TOO_SMALL) ,"key too small"},
|
||||
{ERR_REASON(SSL_R_KRB5) ,"krb5"},
|
||||
{ERR_REASON(SSL_R_KRB5_C_CC_PRINC) ,"krb5 client cc principal (no tkt?)"},
|
||||
{ERR_REASON(SSL_R_KRB5_C_GET_CRED) ,"krb5 client get cred"},
|
||||
@ -623,6 +630,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
|
||||
{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_VERSION_TOO_LOW) ,"version too low"},
|
||||
{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"},
|
||||
|
@ -1353,7 +1353,7 @@ STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
|
||||
{
|
||||
const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
|
||||
if (!ssl_cipher_disabled(s, c))
|
||||
if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
|
||||
{
|
||||
if (!sk)
|
||||
sk = sk_SSL_CIPHER_new_null();
|
||||
@ -1498,7 +1498,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
|
||||
{
|
||||
c=sk_SSL_CIPHER_value(sk,i);
|
||||
/* Skip disabled ciphers */
|
||||
if (ssl_cipher_disabled(s, c))
|
||||
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
|
||||
continue;
|
||||
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
|
||||
if (c->id == SSL3_CK_SCSV)
|
||||
@ -3640,6 +3640,67 @@ int SSL_is_server(SSL *s)
|
||||
return s->server;
|
||||
}
|
||||
|
||||
void SSL_set_security_level(SSL *s, int level)
|
||||
{
|
||||
s->cert->sec_level = level;
|
||||
}
|
||||
|
||||
int SSL_get_security_level(const SSL *s)
|
||||
{
|
||||
return s->cert->sec_level;
|
||||
}
|
||||
|
||||
void SSL_set_security_callback(SSL *s, int (*cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex))
|
||||
{
|
||||
s->cert->sec_cb = cb;
|
||||
}
|
||||
|
||||
int (*SSL_get_security_callback(const SSL *s))(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex)
|
||||
{
|
||||
return s->cert->sec_cb;
|
||||
}
|
||||
|
||||
void SSL_set0_security_ex_data(SSL *s, void *ex)
|
||||
{
|
||||
s->cert->sec_ex = ex;
|
||||
}
|
||||
|
||||
void *SSL_get0_security_ex_data(const SSL *s)
|
||||
{
|
||||
return s->cert->sec_ex;
|
||||
}
|
||||
|
||||
void SSL_CTX_set_security_level(SSL_CTX *ctx, int level)
|
||||
{
|
||||
ctx->cert->sec_level = level;
|
||||
}
|
||||
|
||||
int SSL_CTX_get_security_level(const SSL_CTX *ctx)
|
||||
{
|
||||
return ctx->cert->sec_level;
|
||||
}
|
||||
|
||||
void SSL_CTX_set_security_callback(SSL_CTX *ctx, int (*cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex))
|
||||
{
|
||||
ctx->cert->sec_cb = cb;
|
||||
}
|
||||
|
||||
int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx))(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex)
|
||||
{
|
||||
return ctx->cert->sec_cb;
|
||||
}
|
||||
|
||||
void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex)
|
||||
{
|
||||
ctx->cert->sec_ex = ex;
|
||||
}
|
||||
|
||||
void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx)
|
||||
{
|
||||
return ctx->cert->sec_ex;
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
|
||||
#include "../crypto/bio/bss_file.c"
|
||||
#endif
|
||||
|
@ -627,6 +627,13 @@ typedef struct cert_st
|
||||
unsigned char *ciphers_raw;
|
||||
size_t ciphers_rawlen;
|
||||
|
||||
/* Security callback */
|
||||
int (*sec_cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex);
|
||||
/* Security level */
|
||||
int sec_level;
|
||||
|
||||
void *sec_ex;
|
||||
|
||||
int references; /* >1 only if SSL_copy_session_id is used */
|
||||
} CERT;
|
||||
|
||||
@ -995,10 +1002,10 @@ int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
|
||||
int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);
|
||||
int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
|
||||
const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr);
|
||||
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_add0_chain_cert(CERT *c, X509 *x);
|
||||
int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
|
||||
int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
|
||||
int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
|
||||
int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x);
|
||||
int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x);
|
||||
int ssl_cert_select_current(CERT *c, X509 *x);
|
||||
int ssl_cert_set_current(CERT *c, long arg);
|
||||
X509 *ssl_cert_get0_next_certificate(CERT *c, int first);
|
||||
@ -1006,8 +1013,12 @@ void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg);
|
||||
|
||||
int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
|
||||
int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
|
||||
int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags);
|
||||
int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags);
|
||||
int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref);
|
||||
|
||||
int ssl_security(SSL *s, int op, int bits, int nid, void *other);
|
||||
int ssl_ctx_security(SSL_CTX *ctx, int op, int bits, int nid, void *other);
|
||||
|
||||
int ssl_undefined_function(SSL *s);
|
||||
int ssl_undefined_void_function(void);
|
||||
int ssl_undefined_const_function(const SSL *s);
|
||||
@ -1124,6 +1135,8 @@ int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
|
||||
const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p);
|
||||
long ssl23_default_timeout(void );
|
||||
|
||||
int ssl_allow_compression(SSL *s);
|
||||
|
||||
long tls1_default_timeout(void);
|
||||
int dtls1_do_write(SSL *s,int type);
|
||||
int ssl3_read_n(SSL *s, int n, int max, int extend);
|
||||
@ -1304,6 +1317,7 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
|
||||
const EVP_MD *md);
|
||||
int tls12_get_sigid(const EVP_PKEY *pk);
|
||||
const EVP_MD *tls12_get_hash(unsigned char hash_alg);
|
||||
void ssl_set_sig_mask(unsigned long *pmask_a, SSL *s, int op);
|
||||
|
||||
int tls1_set_sigalgs_list(CERT *c, const char *str, int client);
|
||||
int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client);
|
||||
@ -1315,6 +1329,10 @@ void tls1_set_cert_validity(SSL *s);
|
||||
#ifndef OPENSSL_NO_DH
|
||||
DH *ssl_get_auto_dh(SSL *s);
|
||||
#endif
|
||||
|
||||
int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee);
|
||||
int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *ex, int vfy);
|
||||
|
||||
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
|
||||
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
|
||||
int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
|
||||
@ -1326,12 +1344,14 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
|
||||
int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
||||
int *al);
|
||||
long ssl_get_algorithm2(SSL *s);
|
||||
size_t tls12_copy_sigalgs(SSL *s, unsigned char *out,
|
||||
const unsigned char *psig, size_t psiglen);
|
||||
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
|
||||
size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs);
|
||||
int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
|
||||
const unsigned char *sig, EVP_PKEY *pkey);
|
||||
void ssl_set_client_disabled(SSL *s);
|
||||
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c);
|
||||
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);
|
||||
|
||||
int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
|
||||
int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
|
||||
|
@ -68,11 +68,19 @@ static int ssl_set_cert(CERT *c, X509 *x509);
|
||||
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
|
||||
int SSL_use_certificate(SSL *ssl, X509 *x)
|
||||
{
|
||||
int rv;
|
||||
if (x == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return(0);
|
||||
}
|
||||
rv = ssl_security_cert(ssl, NULL, x, 0, 1);
|
||||
if (rv != 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_cert_inst(&ssl->cert))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
|
||||
@ -393,11 +401,18 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len
|
||||
|
||||
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
int rv;
|
||||
if (x == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return(0);
|
||||
}
|
||||
rv = ssl_security_cert(NULL, ctx, x, 0, 1);
|
||||
if (rv != 1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_cert_inst(&ctx->cert))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
|
||||
|
450
ssl/t1_lib.c
450
ssl/t1_lib.c
@ -222,36 +222,46 @@ void tls1_clear(SSL *s)
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
|
||||
static int nid_list[] =
|
||||
typedef struct
|
||||
{
|
||||
NID_sect163k1, /* sect163k1 (1) */
|
||||
NID_sect163r1, /* sect163r1 (2) */
|
||||
NID_sect163r2, /* sect163r2 (3) */
|
||||
NID_sect193r1, /* sect193r1 (4) */
|
||||
NID_sect193r2, /* sect193r2 (5) */
|
||||
NID_sect233k1, /* sect233k1 (6) */
|
||||
NID_sect233r1, /* sect233r1 (7) */
|
||||
NID_sect239k1, /* sect239k1 (8) */
|
||||
NID_sect283k1, /* sect283k1 (9) */
|
||||
NID_sect283r1, /* sect283r1 (10) */
|
||||
NID_sect409k1, /* sect409k1 (11) */
|
||||
NID_sect409r1, /* sect409r1 (12) */
|
||||
NID_sect571k1, /* sect571k1 (13) */
|
||||
NID_sect571r1, /* sect571r1 (14) */
|
||||
NID_secp160k1, /* secp160k1 (15) */
|
||||
NID_secp160r1, /* secp160r1 (16) */
|
||||
NID_secp160r2, /* secp160r2 (17) */
|
||||
NID_secp192k1, /* secp192k1 (18) */
|
||||
NID_X9_62_prime192v1, /* secp192r1 (19) */
|
||||
NID_secp224k1, /* secp224k1 (20) */
|
||||
NID_secp224r1, /* secp224r1 (21) */
|
||||
NID_secp256k1, /* secp256k1 (22) */
|
||||
NID_X9_62_prime256v1, /* secp256r1 (23) */
|
||||
NID_secp384r1, /* secp384r1 (24) */
|
||||
NID_secp521r1, /* secp521r1 (25) */
|
||||
NID_brainpoolP256r1, /* brainpoolP256r1 (26) */
|
||||
NID_brainpoolP384r1, /* brainpoolP384r1 (27) */
|
||||
NID_brainpoolP512r1 /* brainpool512r1 (28) */
|
||||
int nid; /* Curve NID */
|
||||
int secbits; /* Bits of security (from SP800-57) */
|
||||
unsigned int flags; /* Flags: currently just field type */
|
||||
} tls_curve_info;
|
||||
|
||||
#define TLS_CURVE_CHAR2 0x1
|
||||
#define TLS_CURVE_PRIME 0x0
|
||||
|
||||
static tls_curve_info nid_list[] =
|
||||
{
|
||||
{NID_sect163k1, 80, TLS_CURVE_CHAR2},/* sect163k1 (1) */
|
||||
{NID_sect163r1, 80, TLS_CURVE_CHAR2},/* sect163r1 (2) */
|
||||
{NID_sect163r2, 80, TLS_CURVE_CHAR2},/* sect163r2 (3) */
|
||||
{NID_sect193r1, 80, TLS_CURVE_CHAR2},/* sect193r1 (4) */
|
||||
{NID_sect193r2, 80, TLS_CURVE_CHAR2},/* sect193r2 (5) */
|
||||
{NID_sect233k1, 112, TLS_CURVE_CHAR2},/* sect233k1 (6) */
|
||||
{NID_sect233r1, 112, TLS_CURVE_CHAR2},/* sect233r1 (7) */
|
||||
{NID_sect239k1, 112, TLS_CURVE_CHAR2},/* sect239k1 (8) */
|
||||
{NID_sect283k1, 128, TLS_CURVE_CHAR2},/* sect283k1 (9) */
|
||||
{NID_sect283r1, 128, TLS_CURVE_CHAR2},/* sect283r1 (10) */
|
||||
{NID_sect409k1, 192, TLS_CURVE_CHAR2},/* sect409k1 (11) */
|
||||
{NID_sect409r1, 192, TLS_CURVE_CHAR2},/* sect409r1 (12) */
|
||||
{NID_sect571k1, 256, TLS_CURVE_CHAR2},/* sect571k1 (13) */
|
||||
{NID_sect571r1, 256, TLS_CURVE_CHAR2},/* sect571r1 (14) */
|
||||
{NID_secp160k1, 80, TLS_CURVE_PRIME},/* secp160k1 (15) */
|
||||
{NID_secp160r1, 80, TLS_CURVE_PRIME},/* secp160r1 (16) */
|
||||
{NID_secp160r2, 80, TLS_CURVE_PRIME},/* secp160r2 (17) */
|
||||
{NID_secp192k1, 80, TLS_CURVE_PRIME},/* secp192k1 (18) */
|
||||
{NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME},/* secp192r1 (19) */
|
||||
{NID_secp224k1, 112, TLS_CURVE_PRIME},/* secp224k1 (20) */
|
||||
{NID_secp224r1, 112, TLS_CURVE_PRIME},/* secp224r1 (21) */
|
||||
{NID_secp256k1, 128, TLS_CURVE_PRIME},/* secp256k1 (22) */
|
||||
{NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME},/* secp256r1 (23) */
|
||||
{NID_secp384r1, 192, TLS_CURVE_PRIME},/* secp384r1 (24) */
|
||||
{NID_secp521r1, 256, TLS_CURVE_PRIME},/* secp521r1 (25) */
|
||||
{NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */
|
||||
{NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */
|
||||
{NID_brainpoolP512r1, 256, TLS_CURVE_PRIME},/* brainpool512r1 (28) */
|
||||
};
|
||||
|
||||
|
||||
@ -306,7 +316,7 @@ int tls1_ec_curve_id2nid(int curve_id)
|
||||
if ((curve_id < 1) || ((unsigned int)curve_id >
|
||||
sizeof(nid_list)/sizeof(nid_list[0])))
|
||||
return 0;
|
||||
return nid_list[curve_id-1];
|
||||
return nid_list[curve_id-1].nid;
|
||||
}
|
||||
|
||||
int tls1_ec_nid2curve_id(int nid)
|
||||
@ -414,6 +424,20 @@ static void tls1_get_curvelist(SSL *s, int sess,
|
||||
*pcurveslen = sizeof(eccurves_default);
|
||||
}
|
||||
}
|
||||
|
||||
/* See if curve is allowed by security callback */
|
||||
static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
|
||||
{
|
||||
tls_curve_info *cinfo;
|
||||
if (curve[0])
|
||||
return 1;
|
||||
if ((curve[1] < 1) || ((size_t)curve[1] >
|
||||
sizeof(nid_list)/sizeof(nid_list[0])))
|
||||
return 0;
|
||||
cinfo = &nid_list[curve[1]-1];
|
||||
return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);
|
||||
}
|
||||
|
||||
/* Check a curve is one of our preferences */
|
||||
int tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
|
||||
{
|
||||
@ -445,7 +469,7 @@ int tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
|
||||
for (i = 0; i < curveslen; i += 2, curves += 2)
|
||||
{
|
||||
if (p[1] == curves[0] && p[2] == curves[1])
|
||||
return 1;
|
||||
return tls_curve_allowed(s, p + 1, SSL_SECOP_CURVE_CHECK);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -496,6 +520,8 @@ int tls1_shared_curve(SSL *s, int nmatch)
|
||||
{
|
||||
if (pref[0] == tsupp[0] && pref[1] == tsupp[1])
|
||||
{
|
||||
if (!tls_curve_allowed(s, pref, SSL_SECOP_CURVE_SHARED))
|
||||
continue;
|
||||
if (nmatch == k)
|
||||
{
|
||||
int id = (pref[0] << 8) | pref[1];
|
||||
@ -678,7 +704,7 @@ static int tls1_check_ec_key(SSL *s,
|
||||
return 0;
|
||||
/* For clients can only check sent curve list */
|
||||
if (!s->server)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1005,6 +1031,14 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
|
||||
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,SSL_R_UNKNOWN_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
/* Make sure security callback allows algorithm */
|
||||
if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
|
||||
EVP_MD_size(*pmd) * 4, EVP_MD_type(*pmd),
|
||||
(void *)sig))
|
||||
{
|
||||
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,SSL_R_WRONG_SIGNATURE_TYPE);
|
||||
return 0;
|
||||
}
|
||||
/* Store the digest used so applications can retrieve it if they
|
||||
* wish.
|
||||
*/
|
||||
@ -1012,6 +1046,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
|
||||
s->session->sess_cert->peer_key->digest = *pmd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get a mask of disabled algorithms: an algorithm is disabled
|
||||
* if it isn't supported or doesn't appear in supported signature
|
||||
* algorithms. Unlike ssl_cipher_get_disabled this applies to a specific
|
||||
@ -1021,9 +1056,6 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
|
||||
void ssl_set_client_disabled(SSL *s)
|
||||
{
|
||||
CERT *c = s->cert;
|
||||
const unsigned char *sigalgs;
|
||||
size_t i, sigalgslen;
|
||||
int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
|
||||
c->mask_a = 0;
|
||||
c->mask_k = 0;
|
||||
/* Don't allow TLS 1.2 only ciphers if we don't suppport them */
|
||||
@ -1031,50 +1063,16 @@ void ssl_set_client_disabled(SSL *s)
|
||||
c->mask_ssl = SSL_TLSV1_2;
|
||||
else
|
||||
c->mask_ssl = 0;
|
||||
/* Now go through all signature algorithms seeing if we support
|
||||
* any for RSA, DSA, ECDSA. Do this for all versions not just
|
||||
* TLS 1.2.
|
||||
*/
|
||||
sigalgslen = tls12_get_psigalgs(s, &sigalgs);
|
||||
for (i = 0; i < sigalgslen; i += 2, sigalgs += 2)
|
||||
{
|
||||
switch(sigalgs[1])
|
||||
{
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
case TLSEXT_signature_rsa:
|
||||
have_rsa = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
case TLSEXT_signature_dsa:
|
||||
have_dsa = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDSA
|
||||
case TLSEXT_signature_ecdsa:
|
||||
have_ecdsa = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* Disable auth and static DH if we don't include any appropriate
|
||||
ssl_set_sig_mask(&c->mask_a, s, SSL_SECOP_SIGALG_MASK);
|
||||
/* Disable static DH if we don't include any appropriate
|
||||
* signature algorithms.
|
||||
*/
|
||||
if (!have_rsa)
|
||||
{
|
||||
c->mask_a |= SSL_aRSA;
|
||||
if (c->mask_a & SSL_aRSA)
|
||||
c->mask_k |= SSL_kDHr|SSL_kECDHr;
|
||||
}
|
||||
if (!have_dsa)
|
||||
{
|
||||
c->mask_a |= SSL_aDSS;
|
||||
if (c->mask_a & SSL_aDSS)
|
||||
c->mask_k |= SSL_kDHd;
|
||||
}
|
||||
if (!have_ecdsa)
|
||||
{
|
||||
c->mask_a |= SSL_aECDSA;
|
||||
if (c->mask_a & SSL_aECDSA)
|
||||
c->mask_k |= SSL_kECDHe;
|
||||
}
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if (!kssl_tgt_is_available(s->kssl_ctx))
|
||||
{
|
||||
@ -1093,12 +1091,19 @@ void ssl_set_client_disabled(SSL *s)
|
||||
c->valid = 1;
|
||||
}
|
||||
|
||||
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c)
|
||||
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
|
||||
{
|
||||
CERT *ct = s->cert;
|
||||
if (c->algorithm_ssl & ct->mask_ssl || c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a)
|
||||
return 1;
|
||||
return 0;
|
||||
return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
|
||||
}
|
||||
|
||||
static int tls_use_ticket(SSL *s)
|
||||
{
|
||||
if (s->options & SSL_OP_NO_TICKET)
|
||||
return 0;
|
||||
return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
|
||||
}
|
||||
|
||||
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
|
||||
@ -1231,6 +1236,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
long lenmax;
|
||||
const unsigned char *plist;
|
||||
size_t plistlen;
|
||||
size_t i;
|
||||
unsigned char *etmp;
|
||||
|
||||
tls1_get_formatlist(s, &plist, &plistlen);
|
||||
|
||||
@ -1259,22 +1266,34 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
s2n(TLSEXT_TYPE_elliptic_curves,ret);
|
||||
s2n(plistlen + 2, ret);
|
||||
etmp = ret + 4;
|
||||
/* Copy curve ID if supported */
|
||||
for (i = 0; i < plistlen; i += 2, plist += 2)
|
||||
{
|
||||
if (tls_curve_allowed(s, plist, SSL_SECOP_CURVE_SUPPORTED))
|
||||
{
|
||||
*etmp++ = plist[0];
|
||||
*etmp++ = plist[1];
|
||||
}
|
||||
}
|
||||
|
||||
plistlen = etmp - ret - 4;
|
||||
|
||||
/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
|
||||
* elliptic_curve_list, but the examples use two bytes.
|
||||
* http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
|
||||
* resolves this to two bytes.
|
||||
*/
|
||||
s2n(plistlen + 2, ret);
|
||||
s2n(plistlen, ret);
|
||||
memcpy(ret, plist, plistlen);
|
||||
ret+=plistlen;
|
||||
}
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
|
||||
if (tls_use_ticket(s))
|
||||
{
|
||||
int ticklen;
|
||||
if (!s->new_session && s->session && s->session->tlsext_tick)
|
||||
@ -1314,13 +1333,18 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
{
|
||||
size_t salglen;
|
||||
const unsigned char *salg;
|
||||
unsigned char *etmp;
|
||||
salglen = tls12_get_psigalgs(s, &salg);
|
||||
if ((size_t)(limit - ret) < salglen + 6)
|
||||
return NULL;
|
||||
s2n(TLSEXT_TYPE_signature_algorithms,ret);
|
||||
s2n(salglen + 2, ret);
|
||||
s2n(salglen, ret);
|
||||
memcpy(ret, salg, salglen);
|
||||
etmp = ret;
|
||||
/* Skip over lengths for now */
|
||||
ret += 4;
|
||||
salglen = tls12_copy_sigalgs(s, etmp, salg, salglen);
|
||||
/* Fill in lengths */
|
||||
s2n(salglen + 2, etmp);
|
||||
s2n(salglen, etmp);
|
||||
ret += salglen;
|
||||
}
|
||||
|
||||
@ -1603,8 +1627,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
/* Currently the server should not respond with a SupportedCurves extension */
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
if (s->tlsext_ticket_expected
|
||||
&& !(SSL_get_options(s) & SSL_OP_NO_TICKET))
|
||||
if (s->tlsext_ticket_expected && tls_use_ticket(s))
|
||||
{
|
||||
if ((long)(limit - ret - 4) < 0) return NULL;
|
||||
s2n(TLSEXT_TYPE_session_ticket,ret);
|
||||
@ -2644,8 +2667,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
*al = TLS1_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
|
||||
|| (size > 0))
|
||||
if (!tls_use_ticket(s) || (size > 0))
|
||||
{
|
||||
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
|
||||
return 0;
|
||||
@ -3271,7 +3293,7 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
|
||||
/* If tickets disabled behave as if no ticket present
|
||||
* to permit stateful resumption.
|
||||
*/
|
||||
if (SSL_get_options(s) & SSL_OP_NO_TICKET)
|
||||
if (!tls_use_ticket(s))
|
||||
return 0;
|
||||
if ((s->version <= SSL3_VERSION) || !limit)
|
||||
return 0;
|
||||
@ -3525,40 +3547,60 @@ int tls12_get_sigid(const EVP_PKEY *pk)
|
||||
sizeof(tls12_sig)/sizeof(tls12_lookup));
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nid;
|
||||
int secbits;
|
||||
const EVP_MD *(*mfunc)(void);
|
||||
} tls12_hash_info;
|
||||
|
||||
static const tls12_hash_info tls12_md_info[] = {
|
||||
#ifdef OPENSSL_NO_MD5
|
||||
{NID_md5, 64, 0},
|
||||
#else
|
||||
{NID_md5, 64, EVP_md5},
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_SHA
|
||||
{NID_sha1, 80, 0},
|
||||
#else
|
||||
{NID_sha1, 80, EVP_sha1},
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_SHA256
|
||||
{NID_sha224, 112, 0},
|
||||
{NID_sha256, 128, 0},
|
||||
#else
|
||||
{NID_sha224, 112, EVP_sha224},
|
||||
{NID_sha256, 128, EVP_sha256},
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_SHA512
|
||||
{NID_sha384, 192, 0},
|
||||
{NID_sha512, 256, 0}
|
||||
#else
|
||||
{NID_sha384, 192, EVP_sha384},
|
||||
{NID_sha512, 256, EVP_sha512}
|
||||
#endif
|
||||
};
|
||||
|
||||
static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg)
|
||||
{
|
||||
if (hash_alg == 0)
|
||||
return NULL;
|
||||
if (hash_alg > sizeof(tls12_md_info)/sizeof(tls12_md_info[0]))
|
||||
return NULL;
|
||||
return tls12_md_info + hash_alg - 1;
|
||||
}
|
||||
|
||||
const EVP_MD *tls12_get_hash(unsigned char hash_alg)
|
||||
{
|
||||
switch(hash_alg)
|
||||
{
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
case TLSEXT_hash_md5:
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return NULL;
|
||||
#endif
|
||||
return EVP_md5();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA
|
||||
case TLSEXT_hash_sha1:
|
||||
return EVP_sha1();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA256
|
||||
case TLSEXT_hash_sha224:
|
||||
return EVP_sha224();
|
||||
|
||||
case TLSEXT_hash_sha256:
|
||||
return EVP_sha256();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA512
|
||||
case TLSEXT_hash_sha384:
|
||||
return EVP_sha384();
|
||||
|
||||
case TLSEXT_hash_sha512:
|
||||
return EVP_sha512();
|
||||
#endif
|
||||
default:
|
||||
const tls12_hash_info *inf;
|
||||
#ifndef OPENSSL_FIPS
|
||||
if (hash_alg == TLSEXT_hash_md5 && FIPS_mode())
|
||||
return NULL;
|
||||
|
||||
}
|
||||
#endif
|
||||
inf = tls12_get_hash_info(hash_alg);
|
||||
if (!inf || !inf->mfunc)
|
||||
return NULL;
|
||||
return inf->mfunc();
|
||||
}
|
||||
|
||||
static int tls12_get_pkey_idx(unsigned char sig_alg)
|
||||
@ -3611,8 +3653,86 @@ static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
|
||||
*psignhash_nid = NID_undef;
|
||||
}
|
||||
}
|
||||
/* Check to see if a signature algorithm is allowed */
|
||||
static int tls12_sigalg_allowed(SSL *s, int op, const unsigned char *ptmp)
|
||||
{
|
||||
/* See if we have an entry in the hash table and it is enabled */
|
||||
const tls12_hash_info *hinf = tls12_get_hash_info(ptmp[0]);
|
||||
if (!hinf || !hinf->mfunc)
|
||||
return 0;
|
||||
/* See if public key algorithm allowed */
|
||||
if (tls12_get_pkey_idx(ptmp[1]) == -1)
|
||||
return 0;
|
||||
/* Finally see if security callback allows it */
|
||||
return ssl_security(s, op, hinf->secbits, hinf->nid, (void *)ptmp);
|
||||
}
|
||||
|
||||
/* Get a mask of disabled public key algorithms based on supported
|
||||
* signature algorithms. For example if no signature algorithm supports RSA
|
||||
* then RSA is disabled.
|
||||
*/
|
||||
|
||||
void ssl_set_sig_mask(unsigned long *pmask_a, SSL *s, int op)
|
||||
{
|
||||
const unsigned char *sigalgs;
|
||||
size_t i, sigalgslen;
|
||||
int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
|
||||
/* Now go through all signature algorithms seeing if we support
|
||||
* any for RSA, DSA, ECDSA. Do this for all versions not just
|
||||
* TLS 1.2. To keep down calls to security callback only check
|
||||
* if we have to.
|
||||
*/
|
||||
sigalgslen = tls12_get_psigalgs(s, &sigalgs);
|
||||
for (i = 0; i < sigalgslen; i += 2, sigalgs += 2)
|
||||
{
|
||||
switch(sigalgs[1])
|
||||
{
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
case TLSEXT_signature_rsa:
|
||||
if (!have_rsa && tls12_sigalg_allowed(s, op, sigalgs))
|
||||
have_rsa = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
case TLSEXT_signature_dsa:
|
||||
if (!have_dsa && tls12_sigalg_allowed(s, op, sigalgs))
|
||||
have_dsa = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDSA
|
||||
case TLSEXT_signature_ecdsa:
|
||||
if (!have_ecdsa && tls12_sigalg_allowed(s, op, sigalgs))
|
||||
have_ecdsa = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!have_rsa)
|
||||
*pmask_a |= SSL_aRSA;
|
||||
if (!have_dsa)
|
||||
*pmask_a |= SSL_aDSS;
|
||||
if (!have_ecdsa)
|
||||
*pmask_a |= SSL_aECDSA;
|
||||
}
|
||||
|
||||
size_t tls12_copy_sigalgs(SSL *s, unsigned char *out,
|
||||
const unsigned char *psig, size_t psiglen)
|
||||
{
|
||||
unsigned char *tmpout = out;
|
||||
size_t i;
|
||||
for (i = 0; i < psiglen; i += 2, psig += 2)
|
||||
{
|
||||
if (tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, psig))
|
||||
{
|
||||
*tmpout++ = psig[0];
|
||||
*tmpout++ = psig[1];
|
||||
}
|
||||
}
|
||||
return tmpout - out;
|
||||
}
|
||||
|
||||
/* Given preference and allowed sigalgs set shared sigalgs */
|
||||
static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig,
|
||||
static int tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig,
|
||||
const unsigned char *pref, size_t preflen,
|
||||
const unsigned char *allow, size_t allowlen)
|
||||
{
|
||||
@ -3621,9 +3741,7 @@ static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig,
|
||||
for (i = 0, ptmp = pref; i < preflen; i+=2, ptmp+=2)
|
||||
{
|
||||
/* Skip disabled hashes or signature algorithms */
|
||||
if (tls12_get_hash(ptmp[0]) == NULL)
|
||||
continue;
|
||||
if (tls12_get_pkey_idx(ptmp[1]) == -1)
|
||||
if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, ptmp))
|
||||
continue;
|
||||
for (j = 0, atmp = allow; j < allowlen; j+=2, atmp+=2)
|
||||
{
|
||||
@ -3688,13 +3806,13 @@ static int tls1_set_shared_sigalgs(SSL *s)
|
||||
pref = c->peer_sigalgs;
|
||||
preflen = c->peer_sigalgslen;
|
||||
}
|
||||
nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
|
||||
nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
|
||||
if (!nmatch)
|
||||
return 1;
|
||||
salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
|
||||
if (!salgs)
|
||||
return 0;
|
||||
nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
|
||||
nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
|
||||
c->shared_sigalgs = salgs;
|
||||
c->shared_sigalgslen = nmatch;
|
||||
return 1;
|
||||
@ -4495,3 +4613,87 @@ DH *ssl_get_auto_dh(SSL *s)
|
||||
return DH_get_1024_160();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
|
||||
{
|
||||
int secbits;
|
||||
EVP_PKEY *pkey = X509_get_pubkey(x);
|
||||
if (pkey)
|
||||
{
|
||||
secbits = EVP_PKEY_security_bits(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
else
|
||||
secbits = -1;
|
||||
if (s)
|
||||
return ssl_security(s, op, secbits, 0, x);
|
||||
else
|
||||
return ssl_ctx_security(ctx, op, secbits, 0, x);
|
||||
}
|
||||
|
||||
static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op)
|
||||
{
|
||||
/* Lookup signature algorithm digest */
|
||||
int secbits = -1, md_nid = NID_undef, sig_nid;
|
||||
sig_nid = X509_get_signature_nid(x);
|
||||
if (sig_nid && OBJ_find_sigid_algs(sig_nid, &md_nid, NULL))
|
||||
{
|
||||
const EVP_MD *md;
|
||||
if (md_nid && (md = EVP_get_digestbynid(md_nid)))
|
||||
secbits = EVP_MD_size(md) * 4;
|
||||
}
|
||||
if (s)
|
||||
return ssl_security(s, op, secbits, md_nid, x);
|
||||
else
|
||||
return ssl_ctx_security(ctx, op, secbits, md_nid, x);
|
||||
}
|
||||
|
||||
int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee)
|
||||
{
|
||||
if (vfy)
|
||||
vfy = SSL_SECOP_PEER;
|
||||
if (is_ee)
|
||||
{
|
||||
if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_EE_KEY | vfy))
|
||||
return SSL_R_EE_KEY_TOO_SMALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_CA_KEY | vfy))
|
||||
return SSL_R_CA_KEY_TOO_SMALL;
|
||||
}
|
||||
if (!ssl_security_cert_sig(s, ctx, x, SSL_SECOP_CA_MD | vfy))
|
||||
return SSL_R_CA_MD_TOO_WEAK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check security of a chain, if sk includes the end entity certificate
|
||||
* then x is NULL. If vfy is 1 then we are verifying a peer chain and
|
||||
* not sending one to the peer.
|
||||
* Return values: 1 if ok otherwise error code to use
|
||||
*/
|
||||
|
||||
int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy)
|
||||
{
|
||||
int rv, start_idx, i;
|
||||
if (x == NULL)
|
||||
{
|
||||
x = sk_X509_value(sk, 0);
|
||||
start_idx = 1;
|
||||
}
|
||||
else
|
||||
start_idx = 0;
|
||||
|
||||
rv = ssl_security_cert(s, NULL, x, vfy, 1);
|
||||
if (rv != 1)
|
||||
return rv;
|
||||
|
||||
for (i = start_idx; i < sk_X509_num(sk); i++)
|
||||
{
|
||||
x = sk_X509_value(sk, i);
|
||||
rv = ssl_security_cert(s, NULL, x, vfy, 0);
|
||||
if (rv != 1)
|
||||
return rv;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -157,6 +157,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Default security level if not overriden at config time */
|
||||
#ifndef OPENSSL_TLS_SECURITY_LEVEL
|
||||
#define OPENSSL_TLS_SECURITY_LEVEL 1
|
||||
#endif
|
||||
|
||||
#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0
|
||||
|
||||
#define TLS1_2_VERSION 0x0303
|
||||
|
Loading…
Reference in New Issue
Block a user