Module Name:    src
Committed By:   drochner
Date:           Thu Jan  5 17:32:02 UTC 2012

Modified Files:
        src/crypto/external/bsd/openssl/dist/crypto/x509v3: v3_addr.c
        src/crypto/external/bsd/openssl/dist/engines/ccgost: gost2001_keyx.c
            gost94_keyx.c
        src/crypto/external/bsd/openssl/dist/ssl: d1_pkt.c s3_enc.c s3_srvr.c
            ssl.h ssl3.h ssl_err.c

Log Message:
pull in some patches from upstream CVS, following secadv_20120104.txt:
-rev.21964 for DTLS Plaintext Recovery Attack (CVE-2011-4108)
-rev.21961 for Uninitialized SSL 3.0 Padding (CVE-2011-4576)
-rev.21456+21954 for Malformed RFC 3779 Data Can Cause Assertion Failures
 (CVE-2011-4577)
 (rev.21456 is not mentioned in the advisory, but there is code overlap)
-rev.21958 for SGC Restart DoS Attack (CVE-2011-4619)
-rev.21956 for Invalid GOST parameters DoS Attack (CVE-2012-0027)


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.2 -r1.2 \
    src/crypto/external/bsd/openssl/dist/crypto/x509v3/v3_addr.c
cvs rdiff -u -r1.1.1.1 -r1.2 \
    src/crypto/external/bsd/openssl/dist/engines/ccgost/gost2001_keyx.c \
    src/crypto/external/bsd/openssl/dist/engines/ccgost/gost94_keyx.c
cvs rdiff -u -r1.1.1.4 -r1.2 \
    src/crypto/external/bsd/openssl/dist/ssl/d1_pkt.c \
    src/crypto/external/bsd/openssl/dist/ssl/ssl.h \
    src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c
cvs rdiff -u -r1.3 -r1.4 src/crypto/external/bsd/openssl/dist/ssl/s3_enc.c
cvs rdiff -u -r1.8 -r1.9 src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c
cvs rdiff -u -r1.1.1.3 -r1.2 src/crypto/external/bsd/openssl/dist/ssl/ssl3.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/openssl/dist/crypto/x509v3/v3_addr.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/x509v3/v3_addr.c:1.1.1.2 src/crypto/external/bsd/openssl/dist/crypto/x509v3/v3_addr.c:1.2
--- src/crypto/external/bsd/openssl/dist/crypto/x509v3/v3_addr.c:1.1.1.2	Sun Jun  5 15:00:02 2011
+++ src/crypto/external/bsd/openssl/dist/crypto/x509v3/v3_addr.c	Thu Jan  5 17:32:02 2012
@@ -142,12 +142,13 @@ unsigned int v3_addr_get_afi(const IPAdd
  * Expand the bitstring form of an address into a raw byte array.
  * At the moment this is coded for simplicity, not speed.
  */
-static void addr_expand(unsigned char *addr,
+static int addr_expand(unsigned char *addr,
 			const ASN1_BIT_STRING *bs,
 			const int length,
 			const unsigned char fill)
 {
-  OPENSSL_assert(bs->length >= 0 && bs->length <= length);
+  if (bs->length < 0 || bs->length > length)
+    return 0;
   if (bs->length > 0) {
     memcpy(addr, bs->data, bs->length);
     if ((bs->flags & 7) != 0) {
@@ -159,6 +160,7 @@ static void addr_expand(unsigned char *a
     }
   }
   memset(addr + bs->length, fill, length - bs->length);
+  return 1;
 }
 
 /*
@@ -181,15 +183,13 @@ static int i2r_address(BIO *out,
     return 0;
   switch (afi) {
   case IANA_AFI_IPV4:
-    if (bs->length > 4)
+    if (!addr_expand(addr, bs, 4, fill))
       return 0;
-    addr_expand(addr, bs, 4, fill);
     BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
     break;
   case IANA_AFI_IPV6:
-    if (bs->length > 16)
+    if (!addr_expand(addr, bs, 16, fill))
       return 0;
-    addr_expand(addr, bs, 16, fill);
     for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
       ;
     for (i = 0; i < n; i += 2)
@@ -315,6 +315,12 @@ static int i2r_IPAddrBlocks(const X509V3
 /*
  * Sort comparison function for a sequence of IPAddressOrRange
  * elements.
+ *
+ * There's no sane answer we can give if addr_expand() fails, and an
+ * assertion failure on externally supplied data is seriously uncool,
+ * so we just arbitrarily declare that if given invalid inputs this
+ * function returns -1.  If this messes up your preferred sort order
+ * for garbage input, tough noogies.
  */
 static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
 				const IPAddressOrRange *b,
@@ -326,22 +332,26 @@ static int IPAddressOrRange_cmp(const IP
 
   switch (a->type) {
   case IPAddressOrRange_addressPrefix:
-    addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
+    if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
+      return -1;
     prefixlen_a = addr_prefixlen(a->u.addressPrefix);
     break;
   case IPAddressOrRange_addressRange:
-    addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
+    if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
+      return -1;
     prefixlen_a = length * 8;
     break;
   }
 
   switch (b->type) {
   case IPAddressOrRange_addressPrefix:
-    addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
+    if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
+      return -1;
     prefixlen_b = addr_prefixlen(b->u.addressPrefix);
     break;
   case IPAddressOrRange_addressRange:
-    addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
+    if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
+      return -1;
     prefixlen_b = length * 8;
     break;
   }
@@ -383,6 +393,7 @@ static int range_should_be_prefix(const 
   unsigned char mask;
   int i, j;
 
+  OPENSSL_assert(memcmp(min, max, length) <= 0);
   for (i = 0; i < length && min[i] == max[i]; i++)
     ;
   for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
@@ -656,22 +667,22 @@ int v3_addr_add_range(IPAddrBlocks *addr
 /*
  * Extract min and max values from an IPAddressOrRange.
  */
-static void extract_min_max(IPAddressOrRange *aor,
+static int extract_min_max(IPAddressOrRange *aor,
 			    unsigned char *min,
 			    unsigned char *max,
 			    int length)
 {
-  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+  if (aor == NULL || min == NULL || max == NULL)
+    return 0;
   switch (aor->type) {
   case IPAddressOrRange_addressPrefix:
-    addr_expand(min, aor->u.addressPrefix, length, 0x00);
-    addr_expand(max, aor->u.addressPrefix, length, 0xFF);
-    return;
+    return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
+	    addr_expand(max, aor->u.addressPrefix, length, 0xFF));
   case IPAddressOrRange_addressRange:
-    addr_expand(min, aor->u.addressRange->min, length, 0x00);
-    addr_expand(max, aor->u.addressRange->max, length, 0xFF);
-    return;
+    return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
+	    addr_expand(max, aor->u.addressRange->max, length, 0xFF));
   }
+  return 0;
 }
 
 /*
@@ -687,9 +698,10 @@ int v3_addr_get_range(IPAddressOrRange *
   if (aor == NULL || min == NULL || max == NULL ||
       afi_length == 0 || length < afi_length ||
       (aor->type != IPAddressOrRange_addressPrefix &&
-       aor->type != IPAddressOrRange_addressRange))
+       aor->type != IPAddressOrRange_addressRange) ||
+      !extract_min_max(aor, min, max, afi_length))
     return 0;
-  extract_min_max(aor, min, max, afi_length);
+
   return afi_length;
 }
 
@@ -771,8 +783,9 @@ int v3_addr_is_canonical(IPAddrBlocks *a
       IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
       IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
 
-      extract_min_max(a, a_min, a_max, length);
-      extract_min_max(b, b_min, b_max, length);
+      if (!extract_min_max(a, a_min, a_max, length) ||
+	  !extract_min_max(b, b_min, b_max, length))
+	return 0;
 
       /*
        * Punt misordered list, overlapping start, or inverted range.
@@ -800,14 +813,17 @@ int v3_addr_is_canonical(IPAddrBlocks *a
     }
 
     /*
-     * Check final range to see if it should be a prefix.
+     * Check range to see if it's inverted or should be a
+     * prefix.
      */
     j = sk_IPAddressOrRange_num(aors) - 1;
     {
       IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
-      if (a->type == IPAddressOrRange_addressRange) {
-	extract_min_max(a, a_min, a_max, length);
-	if (range_should_be_prefix(a_min, a_max, length) >= 0)
+      if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+	if (!extract_min_max(a, a_min, a_max, length))
+	  return 0;
+	if (memcmp(a_min, a_max, length) > 0 ||
+	    range_should_be_prefix(a_min, a_max, length) >= 0)
 	  return 0;
       }
     }
@@ -841,8 +857,16 @@ static int IPAddressOrRanges_canonize(IP
     unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
     unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
 
-    extract_min_max(a, a_min, a_max, length);
-    extract_min_max(b, b_min, b_max, length);
+    if (!extract_min_max(a, a_min, a_max, length) ||
+	!extract_min_max(b, b_min, b_max, length))
+      return 0;
+
+    /*
+     * Punt inverted ranges.
+     */
+    if (memcmp(a_min, a_max, length) > 0 ||
+	memcmp(b_min, b_max, length) > 0)
+      return 0;
 
     /*
      * Punt overlaps.
@@ -869,6 +893,20 @@ static int IPAddressOrRanges_canonize(IP
     }
   }
 
+  /*
+   * Check for inverted final range.
+   */
+  j = sk_IPAddressOrRange_num(aors) - 1;
+  {
+    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+    if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+      unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+      extract_min_max(a, a_min, a_max, length);
+      if (memcmp(a_min, a_max, length) > 0)
+	return 0;
+    }
+  }
+
   return 1;
 }
 
@@ -1017,6 +1055,11 @@ static void *v2i_IPAddrBlocks(const stru
 	X509V3_conf_err(val);
 	goto err;
       }
+      if (memcmp(min, max, length_from_afi(afi)) > 0) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+	X509V3_conf_err(val);
+	goto err;
+      }
       if (!v3_addr_add_range(addr, afi, safi, min, max)) {
 	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
 	goto err;
@@ -1102,13 +1145,15 @@ static int addr_contains(IPAddressOrRang
 
   p = 0;
   for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
-    extract_min_max(sk_IPAddressOrRange_value(child, c),
-		    c_min, c_max, length);
+    if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
+			 c_min, c_max, length))
+      return -1;
     for (;; p++) {
       if (p >= sk_IPAddressOrRange_num(parent))
 	return 0;
-      extract_min_max(sk_IPAddressOrRange_value(parent, p),
-		      p_min, p_max, length);
+      if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
+			   p_min, p_max, length))
+	return 0;
       if (memcmp(p_max, c_max, length) < 0)
 	continue;
       if (memcmp(p_min, c_min, length) > 0)

Index: src/crypto/external/bsd/openssl/dist/engines/ccgost/gost2001_keyx.c
diff -u src/crypto/external/bsd/openssl/dist/engines/ccgost/gost2001_keyx.c:1.1.1.1 src/crypto/external/bsd/openssl/dist/engines/ccgost/gost2001_keyx.c:1.2
--- src/crypto/external/bsd/openssl/dist/engines/ccgost/gost2001_keyx.c:1.1.1.1	Sun Jul 19 23:05:33 2009
+++ src/crypto/external/bsd/openssl/dist/engines/ccgost/gost2001_keyx.c	Thu Jan  5 17:32:02 2012
@@ -280,6 +280,10 @@ int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *
 		}
 		
 	param = get_encryption_params(gkt->key_agreement_info->cipher);
+    if(!param){
+        goto err;
+    }
+
 	gost_init(&ctx,param->sblock);	
 	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
 	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
Index: src/crypto/external/bsd/openssl/dist/engines/ccgost/gost94_keyx.c
diff -u src/crypto/external/bsd/openssl/dist/engines/ccgost/gost94_keyx.c:1.1.1.1 src/crypto/external/bsd/openssl/dist/engines/ccgost/gost94_keyx.c:1.2
--- src/crypto/external/bsd/openssl/dist/engines/ccgost/gost94_keyx.c:1.1.1.1	Sun Jul 19 23:05:33 2009
+++ src/crypto/external/bsd/openssl/dist/engines/ccgost/gost94_keyx.c	Thu Jan  5 17:32:02 2012
@@ -261,6 +261,10 @@ int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *
 		}
 
 	param = get_encryption_params(gkt->key_agreement_info->cipher);
+    if(!param){
+        goto err;
+    }
+	
 	gost_init(&cctx,param->sblock);	
 	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
 	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);

Index: src/crypto/external/bsd/openssl/dist/ssl/d1_pkt.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/d1_pkt.c:1.1.1.4 src/crypto/external/bsd/openssl/dist/ssl/d1_pkt.c:1.2
--- src/crypto/external/bsd/openssl/dist/ssl/d1_pkt.c:1.1.1.4	Sun Jun  5 15:00:32 2011
+++ src/crypto/external/bsd/openssl/dist/ssl/d1_pkt.c	Thu Jan  5 17:32:02 2012
@@ -375,6 +375,7 @@ dtls1_process_record(SSL *s)
 	SSL3_RECORD *rr;
 	unsigned int mac_size;
 	unsigned char md[EVP_MAX_MD_SIZE];
+	int decryption_failed_or_bad_record_mac = 0;
 
 
 	rr= &(s->s3->rrec);
@@ -445,7 +446,7 @@ printf("\n");
 			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
 			goto f_err;
 #else
-			goto err;
+			decryption_failed_or_bad_record_mac = 1;
 #endif			
 			}
 		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
@@ -456,17 +457,25 @@ printf("\n");
 			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
 			goto f_err;
 #else
-			goto err;
+			decryption_failed_or_bad_record_mac = 1;
 #endif
 			}
 		rr->length-=mac_size;
 		i=s->method->ssl3_enc->mac(s,md,0);
 		if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
 			{
-			goto err;
+			decryption_failed_or_bad_record_mac = 1;
 			}
 		}
 
+	if (decryption_failed_or_bad_record_mac)
+		{
+		/* decryption failed, silently discard message */
+		rr->length = 0;
+		s->packet_length = 0;
+		goto err;
+		}
+
 	/* r->length is now just compressed */
 	if (s->expand != NULL)
 		{
Index: src/crypto/external/bsd/openssl/dist/ssl/ssl.h
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl.h:1.1.1.4 src/crypto/external/bsd/openssl/dist/ssl/ssl.h:1.2
--- src/crypto/external/bsd/openssl/dist/ssl/ssl.h:1.1.1.4	Sun Jun  5 15:00:44 2011
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl.h	Thu Jan  5 17:32:02 2012
@@ -2024,6 +2024,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL3_CALLBACK_CTRL			 233
 #define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
+#define SSL_F_SSL3_CHECK_CLIENT_HELLO			 315
 #define SSL_F_SSL3_CLIENT_HELLO				 131
 #define SSL_F_SSL3_CONNECT				 132
 #define SSL_F_SSL3_CTRL					 213
@@ -2291,6 +2292,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_MISSING_TMP_RSA_KEY			 172
 #define SSL_R_MISSING_TMP_RSA_PKEY			 173
 #define SSL_R_MISSING_VERIFY_MESSAGE			 174
+#define SSL_R_MULTIPLE_SGC_RESTARTS			 370
 #define SSL_R_NON_SSLV2_INITIAL_PACKET			 175
 #define SSL_R_NO_CERTIFICATES_RETURNED			 176
 #define SSL_R_NO_CERTIFICATE_ASSIGNED			 177
Index: src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c:1.1.1.4 src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c:1.2
--- src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c:1.1.1.4	Sun Jun  5 15:00:47 2011
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c	Thu Jan  5 17:32:02 2012
@@ -137,6 +137,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL),	"SSL3_CALLBACK_CTRL"},
 {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE),	"SSL3_CHANGE_CIPHER_STATE"},
 {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),	"SSL3_CHECK_CERT_AND_ALGORITHM"},
+{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO),	"SSL3_CHECK_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO),	"SSL3_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_CONNECT),	"SSL3_CONNECT"},
 {ERR_FUNC(SSL_F_SSL3_CTRL),	"SSL3_CTRL"},
@@ -407,6 +408,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY)   ,"missing tmp rsa key"},
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY)  ,"missing tmp rsa pkey"},
 {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"},
+{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"},
 {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"},
 {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"},
 {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"},

Index: src/crypto/external/bsd/openssl/dist/ssl/s3_enc.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/s3_enc.c:1.3 src/crypto/external/bsd/openssl/dist/ssl/s3_enc.c:1.4
--- src/crypto/external/bsd/openssl/dist/ssl/s3_enc.c:1.3	Sun Jun  5 23:09:48 2011
+++ src/crypto/external/bsd/openssl/dist/ssl/s3_enc.c	Thu Jan  5 17:32:02 2012
@@ -512,6 +512,9 @@ int ssl3_enc(SSL *s, int send)
 
 			/* we need to add 'i-1' padding bytes */
 			l+=i;
+			/* the last of these zero bytes will be overwritten
+			 * with the padding length. */
+			memset(&rec->input[rec->length], 0, i);
 			rec->length+=i;
 			rec->input[l-1]=(i-1);
 			}

Index: src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c:1.8 src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c:1.9
--- src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c:1.8	Thu Jul  7 18:11:19 2011
+++ src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c	Thu Jan  5 17:32:02 2012
@@ -287,6 +287,7 @@ int ssl3_accept(SSL *s)
 				}
 
 			s->init_num=0;
+			s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 
 			if (s->state != SSL_ST_RENEGOTIATE)
 				{
@@ -836,6 +837,14 @@ int ssl3_check_client_hello(SSL *s)
 	int ok;
 	long n;
 
+	/* We only allow the client to restart the handshake once per
+	 * negotiation. */
+	if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
+		return -1;
+		}
+
 	/* this function is called when we really expect a Certificate message,
 	 * so permit appropriate message length */
 	n=s->method->ssl_get_message(s,
@@ -859,6 +868,7 @@ int ssl3_check_client_hello(SSL *s)
 			s->s3->tmp.dh = NULL;
 			}
 #endif
+		s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
 		return 2;
 		}
 	return 1;

Index: src/crypto/external/bsd/openssl/dist/ssl/ssl3.h
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl3.h:1.1.1.3 src/crypto/external/bsd/openssl/dist/ssl/ssl3.h:1.2
--- src/crypto/external/bsd/openssl/dist/ssl/ssl3.h:1.1.1.3	Sun Jun  5 15:00:45 2011
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl3.h	Thu Jan  5 17:32:02 2012
@@ -384,6 +384,17 @@ typedef struct ssl3_buffer_st
 #define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
 #define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
 #define TLS1_FLAGS_KEEP_HANDSHAKE		0x0020
+ 
+/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
+ * restart a handshake because of MS SGC and so prevents us
+ * from restarting the handshake in a loop. It's reset on a
+ * renegotiation, so effectively limits the client to one restart
+ * per negotiation. This limits the possibility of a DDoS
+ * attack where the client handshakes in a loop using SGC to
+ * restart. Servers which permit renegotiation can still be
+ * effected, but we can't prevent that.
+ */
+#define SSL3_FLAGS_SGC_RESTART_DONE		0x0040
 
 #ifndef OPENSSL_NO_SSL_INTERN
 

Reply via email to