mirror of https://github.com/openssl/openssl.git
				
				
				
			Properly check certificate in case of export ciphers.
Reviewed-by: Matt Caswell <matt@openssl.org> MR #588
This commit is contained in:
		
							parent
							
								
									0fb9990480
								
							
						
					
					
						commit
						26c79d5641
					
				|  | @ -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)); | ||||
|  |  | |||
|  | @ -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)); | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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))) { | ||||
|     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); | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue