提交 b362ccab 编写于 作者: D Dr. Stephen Henson

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...
上级 66f96fe2
......@@ -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);
......
......@@ -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 */
......
......@@ -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
......
......@@ -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);
}
/* 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);
......
......@@ -222,36 +222,46 @@ void tls1_clear(SSL *s)
#ifndef OPENSSL_NO_EC
static int nid_list[] =
typedef struct
{
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, /* 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) */
{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));
}
const EVP_MD *tls12_get_hash(unsigned char hash_alg)
typedef struct
{
switch(hash_alg)
{
#ifndef OPENSSL_NO_MD5
case TLSEXT_hash_md5:
#ifdef OPENSSL_FIPS
if (FIPS_mode())
return NULL;
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
return EVP_md5();
#ifdef OPENSSL_NO_SHA
{NID_sha1, 80, 0},
#else
{NID_sha1, 80, EVP_sha1},
#endif
#ifndef OPENSSL_NO_SHA
case TLSEXT_hash_sha1:
return EVP_sha1();
#ifdef OPENSSL_NO_SHA256
{NID_sha224, 112, 0},
{NID_sha256, 128, 0},
#else
{NID_sha224, 112, EVP_sha224},
{NID_sha256, 128, EVP_sha256},
#endif
#ifndef OPENSSL_NO_SHA256
case TLSEXT_hash_sha224:
return EVP_sha224();
case TLSEXT_hash_sha256:
return EVP_sha256();
#ifdef OPENSSL_NO_SHA512
{NID_sha384, 192, 0},
{NID_sha512, 256, 0}
#else
{NID_sha384, 192, EVP_sha384},
{NID_sha512, 256, EVP_sha512}
#endif
#ifndef OPENSSL_NO_SHA512
case TLSEXT_hash_sha384:
return EVP_sha384();
};
case TLSEXT_hash_sha512:
return EVP_sha512();
#endif
default:
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)
{
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册