提交 26c79d56 编写于 作者: K Kurt Roeckx

Properly check certificate in case of export ciphers.

Reviewed-by: NMatt Caswell <matt@openssl.org>
MR #588
上级 0fb99904
...@@ -237,6 +237,11 @@ void *DH_get_ex_data(DH *d, int idx) ...@@ -237,6 +237,11 @@ void *DH_get_ex_data(DH *d, int idx)
return (CRYPTO_get_ex_data(&d->ex_data, idx)); return (CRYPTO_get_ex_data(&d->ex_data, idx));
} }
int DH_bits(const DH *dh)
{
return BN_num_bits(dh->p);
}
int DH_size(const DH *dh) int DH_size(const DH *dh)
{ {
return (BN_num_bytes(dh->p)); return (BN_num_bytes(dh->p));
......
...@@ -64,6 +64,11 @@ ...@@ -64,6 +64,11 @@
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/rand.h> #include <openssl/rand.h>
int RSA_bits(const RSA *r)
{
return (BN_num_bits(r->n));
}
int RSA_size(const RSA *r) int RSA_size(const RSA *r)
{ {
return (BN_num_bytes(r->n)); return (BN_num_bytes(r->n));
......
...@@ -2,32 +2,38 @@ ...@@ -2,32 +2,38 @@
=head1 NAME =head1 NAME
DH_size - get Diffie-Hellman prime size DH_size, DH_bits - get Diffie-Hellman prime size
=head1 SYNOPSIS =head1 SYNOPSIS
#include <openssl/dh.h> #include <openssl/dh.h>
int DH_size(DH *dh); int DH_size(const DH *dh);
int DH_bits(const DH *dh);
=head1 DESCRIPTION =head1 DESCRIPTION
This function returns the Diffie-Hellman size in bytes. It can be used DH_size() returns the Diffie-Hellman prime size in bytes. It can be used
to determine how much memory must be allocated for the shared secret to determine how much memory must be allocated for the shared secret
computed by DH_compute_key(). computed by DH_compute_key().
B<dh-E<gt>p> must not be B<NULL>. DH_bits() returns the number of significant bits.
B<dh> and B<dh-E<gt>p> must not be B<NULL>.
=head1 RETURN VALUE =head1 RETURN VALUE
The size in bytes. The size.
=head1 SEE ALSO =head1 SEE ALSO
L<dh(3)|dh(3)>, L<DH_generate_key(3)|DH_generate_key(3)> L<dh(3)|dh(3)>, L<DH_generate_key(3)|DH_generate_key(3)>,
L<BN_num_bits(3)|BN_num_bits(3)>
=head1 HISTORY =head1 HISTORY
DH_size() is available in all versions of SSLeay and OpenSSL. DH_size() is available in all versions of SSLeay and OpenSSL.
DH_bits() was added in OpenSSL 1.1.0.
=cut =cut
...@@ -2,32 +2,37 @@ ...@@ -2,32 +2,37 @@
=head1 NAME =head1 NAME
RSA_size - get RSA modulus size RSA_size, RSA_bits - get RSA modulus size
=head1 SYNOPSIS =head1 SYNOPSIS
#include <openssl/rsa.h> #include <openssl/rsa.h>
int RSA_size(const RSA *rsa); int RSA_size(const RSA *rsa);
int RSA_bits(const RSA *rsa);
=head1 DESCRIPTION =head1 DESCRIPTION
This function returns the RSA modulus size in bytes. It can be used to RSA_size() returns the RSA modulus size in bytes. It can be used to
determine how much memory must be allocated for an RSA encrypted determine how much memory must be allocated for an RSA encrypted
value. value.
B<rsa-E<gt>n> must not be B<NULL>. RSA_bits() returns the number of significant bits.
B<rsa> and B<rsa-E<gt>n> must not be B<NULL>.
=head1 RETURN VALUE =head1 RETURN VALUE
The size in bytes. The size.
=head1 SEE ALSO =head1 SEE ALSO
L<rsa(3)|rsa(3)> L<rsa(3)|rsa(3)>, L<BN_num_bits(3)|BN_num_bits(3)>
=head1 HISTORY =head1 HISTORY
RSA_size() is available in all versions of SSLeay and OpenSSL. RSA_size() is available in all versions of SSLeay and OpenSSL.
RSA_bits() was added in OpenSSL 1.1.0.
=cut =cut
...@@ -12,8 +12,6 @@ dh - Diffie-Hellman key agreement ...@@ -12,8 +12,6 @@ dh - Diffie-Hellman key agreement
DH * DH_new(void); DH * DH_new(void);
void DH_free(DH *dh); void DH_free(DH *dh);
int DH_size(const DH *dh);
DH * DH_generate_parameters(int prime_len, int generator, DH * DH_generate_parameters(int prime_len, int generator,
void (*callback)(int, int, void *), void *cb_arg); void (*callback)(int, int, void *), void *cb_arg);
int DH_check(const DH *dh, int *codes); int DH_check(const DH *dh, int *codes);
......
...@@ -26,8 +26,6 @@ rsa - RSA public key cryptosystem ...@@ -26,8 +26,6 @@ rsa - RSA public key cryptosystem
int RSA_verify(int type, unsigned char *m, unsigned int m_len, int RSA_verify(int type, unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa); unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
int RSA_size(const RSA *rsa);
RSA *RSA_generate_key(int num, unsigned long e, RSA *RSA_generate_key(int num, unsigned long e,
void (*callback)(int,int,void *), void *cb_arg); void (*callback)(int,int,void *), void *cb_arg);
......
...@@ -200,6 +200,7 @@ DH *DH_new_method(ENGINE *engine); ...@@ -200,6 +200,7 @@ DH *DH_new_method(ENGINE *engine);
DH *DH_new(void); DH *DH_new(void);
void DH_free(DH *dh); void DH_free(DH *dh);
int DH_up_ref(DH *dh); int DH_up_ref(DH *dh);
int DH_bits(const DH *dh);
int DH_size(const DH *dh); int DH_size(const DH *dh);
int DH_security_bits(const DH *dh); int DH_security_bits(const DH *dh);
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
......
...@@ -319,6 +319,7 @@ struct rsa_st { ...@@ -319,6 +319,7 @@ struct rsa_st {
RSA *RSA_new(void); RSA *RSA_new(void);
RSA *RSA_new_method(ENGINE *engine); RSA *RSA_new_method(ENGINE *engine);
int RSA_bits(const RSA *rsa);
int RSA_size(const RSA *rsa); int RSA_size(const RSA *rsa);
int RSA_security_bits(const RSA *rsa); int RSA_security_bits(const RSA *rsa);
......
...@@ -3335,6 +3335,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) ...@@ -3335,6 +3335,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
DH *dh; DH *dh;
#endif #endif
int al = SSL_AD_HANDSHAKE_FAILURE;
alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
alg_a = s->s3->tmp.new_cipher->algorithm_auth; alg_a = s->s3->tmp.new_cipher->algorithm_auth;
...@@ -3395,17 +3396,33 @@ int ssl3_check_cert_and_algorithm(SSL *s) ...@@ -3395,17 +3396,33 @@ int ssl3_check_cert_and_algorithm(SSL *s)
} }
#endif #endif
#ifndef OPENSSL_NO_RSA #ifndef OPENSSL_NO_RSA
if ((alg_k & SSL_kRSA) && if (alg_k & SSL_kRSA) {
!(has_bits(i, EVP_PK_RSA | EVP_PKT_ENC) || (rsa != NULL))) { if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
SSL_R_MISSING_RSA_ENCRYPTING_CERT); SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
goto f_err; SSL_R_MISSING_RSA_ENCRYPTING_CERT);
goto f_err;
} else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
SSL_R_MISSING_RSA_ENCRYPTING_CERT);
goto f_err;
}
if (rsa != NULL) {
/* server key exchange is not allowed. */
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
goto f_err;
}
}
}
} }
#endif #endif
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
if ((alg_k & SSL_kDHE) && if ((alg_k & SSL_kDHE) && (dh == NULL)) {
!(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || (dh != NULL))) { al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_DH_KEY); SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
goto f_err; goto f_err;
} else if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) && } else if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) &&
!has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) {
...@@ -3427,9 +3444,14 @@ int ssl3_check_cert_and_algorithm(SSL *s) ...@@ -3427,9 +3444,14 @@ int ssl3_check_cert_and_algorithm(SSL *s)
pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
#ifndef OPENSSL_NO_RSA #ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA) { if (alg_k & SSL_kRSA) {
if (rsa == NULL if (rsa == NULL) {
|| RSA_size(rsa) * 8 > SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
goto f_err;
} else if (RSA_bits(rsa) >
SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
/* We have a temporary RSA key but it's too large. */
al = SSL_AD_EXPORT_RESTRICTION;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
SSL_R_MISSING_EXPORT_TMP_RSA_KEY); SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
goto f_err; goto f_err;
...@@ -3437,14 +3459,21 @@ int ssl3_check_cert_and_algorithm(SSL *s) ...@@ -3437,14 +3459,21 @@ int ssl3_check_cert_and_algorithm(SSL *s)
} else } else
#endif #endif
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) { if (alg_k & SSL_kDHE) {
if (dh == NULL if (DH_bits(dh) >
|| DH_size(dh) * 8 >
SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
/* We have a temporary DH key but it's too large. */
al = SSL_AD_EXPORT_RESTRICTION;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
SSL_R_MISSING_EXPORT_TMP_DH_KEY); SSL_R_MISSING_EXPORT_TMP_DH_KEY);
goto f_err; goto f_err;
} }
} else if (alg_k & (SSL_kDHr | SSL_kDHd)) {
/* The cert should have had an export DH key. */
al = SSL_AD_EXPORT_RESTRICTION;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
SSL_R_MISSING_EXPORT_TMP_DH_KEY);
goto f_err;
} else } else
#endif #endif
{ {
...@@ -3455,7 +3484,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) ...@@ -3455,7 +3484,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
} }
return (1); return (1);
f_err: f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); ssl3_send_alert(s, SSL3_AL_FATAL, al);
err: err:
return (0); return (0);
} }
......
...@@ -4571,3 +4571,5 @@ ASN1_INTEGER_get_uint64 4929 EXIST::FUNCTION: ...@@ -4571,3 +4571,5 @@ ASN1_INTEGER_get_uint64 4929 EXIST::FUNCTION:
ASN1_INTEGER_set_uint64 4930 EXIST::FUNCTION: ASN1_INTEGER_set_uint64 4930 EXIST::FUNCTION:
PKCS5_pbe2_set_scrypt 4931 EXIST::FUNCTION: PKCS5_pbe2_set_scrypt 4931 EXIST::FUNCTION:
PKCS8_set0_pbe 4932 EXIST::FUNCTION: PKCS8_set0_pbe 4932 EXIST::FUNCTION:
DH_bits 4933 EXIST::FUNCTION:DH
RSA_bits 4934 EXIST::FUNCTION:RSA
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册