aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/dh/dh_lib.c5
-rw-r--r--crypto/rsa/rsa_crpt.c5
-rw-r--r--doc/crypto/DH_size.pod20
-rw-r--r--doc/crypto/RSA_size.pod19
-rw-r--r--doc/crypto/dh.pod2
-rw-r--r--doc/crypto/rsa.pod2
-rw-r--r--include/openssl/dh.h1
-rw-r--r--include/openssl/rsa.h1
-rw-r--r--ssl/s3_clnt.c57
-rwxr-xr-xutil/libeay.num2
10 files changed, 82 insertions, 32 deletions
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index 4a37adc9f8..cce2514bbf 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -237,6 +237,11 @@ void *DH_get_ex_data(DH *d, int 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)
{
return (BN_num_bytes(dh->p));
diff --git a/crypto/rsa/rsa_crpt.c b/crypto/rsa/rsa_crpt.c
index 5220b7d068..3c4fd67714 100644
--- a/crypto/rsa/rsa_crpt.c
+++ b/crypto/rsa/rsa_crpt.c
@@ -64,6 +64,11 @@
#include <openssl/rsa.h>
#include <openssl/rand.h>
+int RSA_bits(const RSA *r)
+{
+ return (BN_num_bits(r->n));
+}
+
int RSA_size(const RSA *r)
{
return (BN_num_bytes(r->n));
diff --git a/doc/crypto/DH_size.pod b/doc/crypto/DH_size.pod
index 97f26fda78..e73f32589a 100644
--- a/doc/crypto/DH_size.pod
+++ b/doc/crypto/DH_size.pod
@@ -2,32 +2,38 @@
=head1 NAME
-DH_size - get Diffie-Hellman prime size
+DH_size, DH_bits - get Diffie-Hellman prime size
=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
-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
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
-The size in bytes.
+The size.
=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
DH_size() is available in all versions of SSLeay and OpenSSL.
+DH_bits() was added in OpenSSL 1.1.0.
=cut
diff --git a/doc/crypto/RSA_size.pod b/doc/crypto/RSA_size.pod
index 5b7f835f95..f68d5e8e3c 100644
--- a/doc/crypto/RSA_size.pod
+++ b/doc/crypto/RSA_size.pod
@@ -2,32 +2,37 @@
=head1 NAME
-RSA_size - get RSA modulus size
+RSA_size, RSA_bits - get RSA modulus size
=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
-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
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
-The size in bytes.
+The size.
=head1 SEE ALSO
-L<rsa(3)|rsa(3)>
+L<rsa(3)|rsa(3)>, L<BN_num_bits(3)|BN_num_bits(3)>
=head1 HISTORY
RSA_size() is available in all versions of SSLeay and OpenSSL.
+RSA_bits() was added in OpenSSL 1.1.0.
=cut
diff --git a/doc/crypto/dh.pod b/doc/crypto/dh.pod
index c3ccd06207..1c8a327458 100644
--- a/doc/crypto/dh.pod
+++ b/doc/crypto/dh.pod
@@ -12,8 +12,6 @@ dh - Diffie-Hellman key agreement
DH * DH_new(void);
void DH_free(DH *dh);
- int DH_size(const DH *dh);
-
DH * DH_generate_parameters(int prime_len, int generator,
void (*callback)(int, int, void *), void *cb_arg);
int DH_check(const DH *dh, int *codes);
diff --git a/doc/crypto/rsa.pod b/doc/crypto/rsa.pod
index 45ac53ffc1..743334ff79 100644
--- a/doc/crypto/rsa.pod
+++ b/doc/crypto/rsa.pod
@@ -26,8 +26,6 @@ rsa - RSA public key cryptosystem
int RSA_verify(int type, unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
- int RSA_size(const RSA *rsa);
-
RSA *RSA_generate_key(int num, unsigned long e,
void (*callback)(int,int,void *), void *cb_arg);
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index 2d7c739eca..e0f4b57349 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -200,6 +200,7 @@ DH *DH_new_method(ENGINE *engine);
DH *DH_new(void);
void DH_free(DH *dh);
int DH_up_ref(DH *dh);
+int DH_bits(const DH *dh);
int DH_size(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,
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index 9ba64970b6..727b9df4c4 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -319,6 +319,7 @@ struct rsa_st {
RSA *RSA_new(void);
RSA *RSA_new_method(ENGINE *engine);
+int RSA_bits(const RSA *rsa);
int RSA_size(const RSA *rsa);
int RSA_security_bits(const RSA *rsa);
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 632d743871..2f7b093c3d 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -3335,6 +3335,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
#ifndef OPENSSL_NO_DH
DH *dh;
#endif
+ int al = SSL_AD_HANDSHAKE_FAILURE;
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -3395,17 +3396,33 @@ int ssl3_check_cert_and_algorithm(SSL *s)
}
#endif
#ifndef OPENSSL_NO_RSA
- if ((alg_k & SSL_kRSA) &&
- !(has_bits(i, EVP_PK_RSA | EVP_PKT_ENC) || (rsa != NULL))) {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
- SSL_R_MISSING_RSA_ENCRYPTING_CERT);
- goto f_err;
+ if (alg_k & SSL_kRSA) {
+ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+ !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;
+ } 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
#ifndef OPENSSL_NO_DH
- if ((alg_k & SSL_kDHE) &&
- !(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || (dh != NULL))) {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_DH_KEY);
+ if ((alg_k & SSL_kDHE) && (dh == NULL)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
goto f_err;
} else if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) &&
!has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) {
@@ -3427,9 +3444,14 @@ int ssl3_check_cert_and_algorithm(SSL *s)
pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA) {
- if (rsa == NULL
- || RSA_size(rsa) * 8 >
+ if (rsa == NULL) {
+ 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)) {
+ /* We have a temporary RSA key but it's too large. */
+ al = SSL_AD_EXPORT_RESTRICTION;
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
goto f_err;
@@ -3437,14 +3459,21 @@ int ssl3_check_cert_and_algorithm(SSL *s)
} else
#endif
#ifndef OPENSSL_NO_DH
- if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) {
- if (dh == NULL
- || DH_size(dh) * 8 >
+ if (alg_k & SSL_kDHE) {
+ if (DH_bits(dh) >
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,
SSL_R_MISSING_EXPORT_TMP_DH_KEY);
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
#endif
{
@@ -3455,7 +3484,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
}
return (1);
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
return (0);
}
diff --git a/util/libeay.num b/util/libeay.num
index c297ef789d..edeb50d34f 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -4571,3 +4571,5 @@ ASN1_INTEGER_get_uint64 4929 EXIST::FUNCTION:
ASN1_INTEGER_set_uint64 4930 EXIST::FUNCTION:
PKCS5_pbe2_set_scrypt 4931 EXIST::FUNCTION:
PKCS8_set0_pbe 4932 EXIST::FUNCTION:
+DH_bits 4933 EXIST::FUNCTION:DH
+RSA_bits 4934 EXIST::FUNCTION:RSA