Blame SOURCES/openssl-1.0.1e-cve-2015-4000.patch

0138da
diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod.logjam openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
0138da
--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod.logjam	2013-02-11 16:02:48.000000000 +0100
0138da
+++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod	2015-05-25 11:37:08.893049771 +0200
0138da
@@ -12,12 +12,10 @@ SSL_CTX_set_tmp_dh_callback, SSL_CTX_set
0138da
             DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
0138da
  long SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh);
0138da
 
0138da
- void SSL_set_tmp_dh_callback(SSL_CTX *ctx,
0138da
+ void SSL_set_tmp_dh_callback(SSL *ctx,
0138da
             DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
0138da
  long SSL_set_tmp_dh(SSL *ssl, DH *dh)
0138da
 
0138da
- DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
0138da
-
0138da
 =head1 DESCRIPTION
0138da
 
0138da
 SSL_CTX_set_tmp_dh_callback() sets the callback function for B<ctx> to be
0138da
@@ -50,24 +48,25 @@ even if he gets hold of the normal (cert
0138da
 only used for signing.
0138da
 
0138da
 In order to perform a DH key exchange the server must use a DH group
0138da
-(DH parameters) and generate a DH key. The server will always generate a new
0138da
-DH key during the negotiation, when the DH parameters are supplied via
0138da
-callback and/or when the SSL_OP_SINGLE_DH_USE option of
0138da
-L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)> is set. It will
0138da
-immediately create a DH key, when DH parameters are supplied via
0138da
-SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. In this case,
0138da
+(DH parameters) and generate a DH key.
0138da
+The server will always generate a new DH key during the negotiation
0138da
+if either the DH parameters are supplied via callback or the
0138da
+SSL_OP_SINGLE_DH_USE option of SSL_CTX_set_options(3) is set (or both).
0138da
+It will  immediately create a DH key if DH parameters are supplied via
0138da
+SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set.
0138da
+In this case,
0138da
 it may happen that a key is generated on initialization without later
0138da
 being needed, while on the other hand the computer time during the
0138da
 negotiation is being saved.
0138da
 
0138da
 If "strong" primes were used to generate the DH parameters, it is not strictly
0138da
 necessary to generate a new key for each handshake but it does improve forward
0138da
-secrecy. If it is not assured, that "strong" primes were used (see especially
0138da
-the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used
0138da
-in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE
0138da
-has an impact on the computer time needed during negotiation, but it is not
0138da
-very large, so application authors/users should consider to always enable
0138da
-this option.
0138da
+secrecy. If it is not assured that "strong" primes were used,
0138da
+SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup
0138da
+attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the
0138da
+computer time needed during negotiation, but it is not very large, so
0138da
+application authors/users should consider always enabling this option.
0138da
+The option is required to implement perfect forward secrecy (PFS).
0138da
 
0138da
 As generating DH parameters is extremely time consuming, an application
0138da
 should not generate the parameters on the fly but supply the parameters.
0138da
@@ -75,82 +74,62 @@ DH parameters can be reused, as the actu
0138da
 the negotiation. The risk in reusing DH parameters is that an attacker
0138da
 may specialize on a very often used DH group. Applications should therefore
0138da
 generate their own DH parameters during the installation process using the
0138da
-openssl L<dhparam(1)|dhparam(1)> application. In order to reduce the computer
0138da
-time needed for this generation, it is possible to use DSA parameters
0138da
-instead (see L<dhparam(1)|dhparam(1)>), but in this case SSL_OP_SINGLE_DH_USE
0138da
-is mandatory.
0138da
+openssl L<dhparam(1)|dhparam(1)> application. This application
0138da
+guarantees that "strong" primes are used.
0138da
 
0138da
-Application authors may compile in DH parameters. Files dh512.pem,
0138da
-dh1024.pem, dh2048.pem, and dh4096 in the 'apps' directory of current
0138da
+Files dh2048.pem, and dh4096.pem in the 'apps' directory of the current
0138da
 version of the OpenSSL distribution contain the 'SKIP' DH parameters,
0138da
 which use safe primes and were generated verifiably pseudo-randomly.
0138da
 These files can be converted into C code using the B<-C> option of the
0138da
-L<dhparam(1)|dhparam(1)> application.
0138da
-Authors may also generate their own set of parameters using
0138da
-L<dhparam(1)|dhparam(1)>, but a user may not be sure how the parameters were
0138da
-generated. The generation of DH parameters during installation is therefore
0138da
-recommended.
0138da
+L<dhparam(1)|dhparam(1)> application. Generation of custom DH
0138da
+parameters during installation should still be preferred to stop an
0138da
+attacker from specializing on a commonly used group. Files dh1024.pem
0138da
+and dh512.pem contain old parameters that must not be used by
0138da
+applications.
0138da
 
0138da
 An application may either directly specify the DH parameters or
0138da
-can supply the DH parameters via a callback function. The callback approach
0138da
-has the advantage, that the callback may supply DH parameters for different
0138da
-key lengths.
0138da
-
0138da
-The B<tmp_dh_callback> is called with the B<keylength> needed and
0138da
-the B<is_export> information. The B<is_export> flag is set, when the
0138da
-ephemeral DH key exchange is performed with an export cipher.
0138da
+can supply the DH parameters via a callback function.
0138da
+
0138da
+Previous versions of the callback used B<is_export> and B<keylength>
0138da
+parameters to control parameter generation for export and non-export
0138da
+cipher suites. Modern servers that do not support export ciphersuites
0138da
+are advised to either use SSL_CTX_set_tmp_dh() in combination with
0138da
+SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore
0138da
+B<keylength> and B<is_export> and simply supply at least 2048-bit
0138da
+parameters in the callback.
0138da
 
0138da
 =head1 EXAMPLES
0138da
 
0138da
-Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling
0138da
+Setup DH parameters with a key length of 2048 bits. (Error handling
0138da
 partly left out.)
0138da
 
0138da
- ...
0138da
- /* Set up ephemeral DH stuff */
0138da
- DH *dh_512 = NULL;
0138da
- DH *dh_1024 = NULL;
0138da
- FILE *paramfile;
0138da
+ Command-line parameter generation:
0138da
+ $ openssl dhparam -out dh_param_2048.pem 2048
0138da
 
0138da
+ Code for setting up parameters during server initialization:
0138da
+
0138da
+ ...
0138da
+ SSL_CTX ctx = SSL_CTX_new();
0138da
  ...
0138da
- /* "openssl dhparam -out dh_param_512.pem -2 512" */
0138da
- paramfile = fopen("dh_param_512.pem", "r");
0138da
+
0138da
+ /* Set up ephemeral DH parameters. */
0138da
+ DH *dh_2048 = NULL;
0138da
+ FILE *paramfile;
0138da
+ paramfile = fopen("dh_param_2048.pem", "r");
0138da
  if (paramfile) {
0138da
-   dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
0138da
+   dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
0138da
    fclose(paramfile);
0138da
+ } else {
0138da
+   /* Error. */
0138da
  }
0138da
- /* "openssl dhparam -out dh_param_1024.pem -2 1024" */
0138da
- paramfile = fopen("dh_param_1024.pem", "r");
0138da
- if (paramfile) {
0138da
-   dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
0138da
-   fclose(paramfile);
0138da
+ if (dh_2048 == NULL) {
0138da
+  /* Error. */
0138da
  }
0138da
- ...
0138da
-
0138da
- /* "openssl dhparam -C -2 512" etc... */
0138da
- DH *get_dh512() { ... }
0138da
- DH *get_dh1024() { ... }
0138da
-
0138da
- DH *tmp_dh_callback(SSL *s, int is_export, int keylength)
0138da
- {
0138da
-    DH *dh_tmp=NULL;
0138da
-
0138da
-    switch (keylength) {
0138da
-    case 512:
0138da
-      if (!dh_512)
0138da
-        dh_512 = get_dh512();
0138da
-      dh_tmp = dh_512;
0138da
-      break;
0138da
-    case 1024:
0138da
-      if (!dh_1024) 
0138da
-        dh_1024 = get_dh1024();
0138da
-      dh_tmp = dh_1024;
0138da
-      break;
0138da
-    default:
0138da
-      /* Generating a key on the fly is very costly, so use what is there */
0138da
-      setup_dh_parameters_like_above();
0138da
-    }
0138da
-    return(dh_tmp);
0138da
+ if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) {
0138da
+   /* Error. */
0138da
  }
0138da
+ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
0138da
+ ...
0138da
 
0138da
 =head1 RETURN VALUES
0138da
 
0138da
diff -up openssl-1.0.1e/ssl/ssl_err.c.logjam openssl-1.0.1e/ssl/ssl_err.c
0138da
--- openssl-1.0.1e/ssl/ssl_err.c.logjam	2015-05-25 11:38:29.834858712 +0200
0138da
+++ openssl-1.0.1e/ssl/ssl_err.c	2015-05-25 11:42:01.041578905 +0200
0138da
@@ -361,6 +361,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
0138da
 {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG)  ,"data length too long"},
0138da
 {ERR_REASON(SSL_R_DECRYPTION_FAILED)     ,"decryption failed"},
0138da
 {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
0138da
+{ERR_REASON(SSL_R_DH_KEY_TOO_SMALL)      ,"dh key too small"},
0138da
 {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
0138da
 {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED)   ,"digest check failed"},
0138da
 {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG)  ,"dtls message too big"},
0138da
diff -up openssl-1.0.1e/ssl/ssl.h.logjam openssl-1.0.1e/ssl/ssl.h
0138da
--- openssl-1.0.1e/ssl/ssl.h.logjam	2015-05-25 11:38:29.834858712 +0200
0138da
+++ openssl-1.0.1e/ssl/ssl.h	2015-05-25 11:40:42.482823220 +0200
0138da
@@ -2289,6 +2289,7 @@ void ERR_load_SSL_strings(void);
0138da
 #define SSL_R_DATA_LENGTH_TOO_LONG			 146
0138da
 #define SSL_R_DECRYPTION_FAILED				 147
0138da
 #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 281
0138da
+#define SSL_R_DH_KEY_TOO_SMALL                           372
0138da
 #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
0138da
 #define SSL_R_DIGEST_CHECK_FAILED			 149
0138da
 #define SSL_R_DTLS_MESSAGE_TOO_BIG			 334
0138da
diff -up openssl-1.0.1e/ssl/s3_clnt.c.logjam openssl-1.0.1e/ssl/s3_clnt.c
0138da
--- openssl-1.0.1e/ssl/s3_clnt.c.logjam	2015-05-25 11:38:29.833858690 +0200
0138da
+++ openssl-1.0.1e/ssl/s3_clnt.c	2015-05-25 11:51:05.845754562 +0200
0138da
@@ -3277,24 +3277,34 @@ int ssl3_check_cert_and_algorithm(SSL *s
0138da
 		}
0138da
 #endif
0138da
 #ifndef OPENSSL_NO_DH
0138da
-	if ((alg_k & SSL_kEDH) &&
0138da
-		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
0138da
+	if ((alg_k & SSL_kEDH) && dh == NULL)
0138da
 		{
0138da
-		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
0138da
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
0138da
 		goto f_err;
0138da
 		}
0138da
-	else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
0138da
+	if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
0138da
 		{
0138da
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
0138da
 		goto f_err;
0138da
 		}
0138da
 #ifndef OPENSSL_NO_DSA
0138da
-	else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
0138da
+	if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
0138da
 		{
0138da
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
0138da
 		goto f_err;
0138da
 		}
0138da
 #endif
0138da
+	/* Check DHE only: static DH not implemented. */
0138da
+	if (alg_k & SSL_kEDH)
0138da
+		{
0138da
+		int dh_size = BN_num_bits(dh->p);
0138da
+		if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768)
0138da
+		    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512))
0138da
+			{
0138da
+			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL);
0138da
+			goto f_err;
0138da
+			}
0138da
+		}
0138da
 #endif
0138da
 
0138da
 	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))