Home | History | Annotate | Download | only in patches
      1 diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
      2 index 882e356..396c408 100644
      3 --- a/nss/lib/ssl/ssl3con.c
      4 +++ b/nss/lib/ssl/ssl3con.c
      5 @@ -7594,6 +7594,33 @@ ssl3_SendClientSecondRound(sslSocket *ss)
      6  
      7      ssl_ReleaseXmitBufLock(ss);		/*******************************/
      8  
      9 +    if (!ss->ssl3.hs.isResuming &&
     10 +        ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) {
     11 +        /* If we are negotiating ChannelID on a full handshake then we record
     12 +         * the handshake hashes in |sid| at this point. They will be needed in
     13 +         * the event that we resume this session and use ChannelID on the
     14 +         * resumption handshake. */
     15 +        SSL3Hashes hashes;
     16 +        SECItem *originalHandshakeHash =
     17 +            &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
     18 +        PORT_Assert(ss->sec.ci.sid->cached == never_cached);
     19 +
     20 +        ssl_GetSpecReadLock(ss);
     21 +        PORT_Assert(ss->version > SSL_LIBRARY_VERSION_3_0);
     22 +        rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
     23 +        ssl_ReleaseSpecReadLock(ss);
     24 +        if (rv != SECSuccess) {
     25 +            return rv;
     26 +        }
     27 +
     28 +        PORT_Assert(originalHandshakeHash->len == 0);
     29 +        originalHandshakeHash->data = PORT_Alloc(hashes.len);
     30 +        if (!originalHandshakeHash->data)
     31 +            return SECFailure;
     32 +        originalHandshakeHash->len = hashes.len;
     33 +        memcpy(originalHandshakeHash->data, hashes.u.raw, hashes.len);
     34 +    }
     35 +
     36      if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
     37  	ss->ssl3.hs.ws = wait_new_session_ticket;
     38      else
     39 @@ -10590,6 +10617,7 @@ static SECStatus
     40  ssl3_SendEncryptedExtensions(sslSocket *ss)
     41  {
     42      static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature";
     43 +    static const char CHANNEL_ID_RESUMPTION_MAGIC[] = "Resumption";
     44      /* This is the ASN.1 prefix for a P-256 public key. Specifically it's:
     45       * SEQUENCE
     46       *   SEQUENCE
     47 @@ -10615,7 +10643,10 @@ ssl3_SendEncryptedExtensions(sslSocket *ss)
     48      SECItem *spki = NULL;
     49      SSL3Hashes hashes;
     50      const unsigned char *pub_bytes;
     51 -    unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + sizeof(SSL3Hashes)];
     52 +    unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) +
     53 +                              sizeof(CHANNEL_ID_RESUMPTION_MAGIC) +
     54 +                              sizeof(SSL3Hashes)*2];
     55 +    size_t signed_data_len;
     56      unsigned char digest[SHA256_LENGTH];
     57      SECItem digest_item;
     58      unsigned char signature[64];
     59 @@ -10665,11 +10696,26 @@ ssl3_SendEncryptedExtensions(sslSocket *ss)
     60  
     61      pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX);
     62  
     63 -    memcpy(signed_data, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC));
     64 -    memcpy(signed_data + sizeof(CHANNEL_ID_MAGIC), hashes.u.raw, hashes.len);
     65 +    signed_data_len = 0;
     66 +    memcpy(signed_data + signed_data_len, CHANNEL_ID_MAGIC,
     67 +           sizeof(CHANNEL_ID_MAGIC));
     68 +    signed_data_len += sizeof(CHANNEL_ID_MAGIC);
     69 +    if (ss->ssl3.hs.isResuming) {
     70 +        SECItem *originalHandshakeHash =
     71 +            &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
     72 +        PORT_Assert(originalHandshakeHash->len > 0);
     73  
     74 -    rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data,
     75 -		      sizeof(CHANNEL_ID_MAGIC) + hashes.len);
     76 +        memcpy(signed_data + signed_data_len, CHANNEL_ID_RESUMPTION_MAGIC,
     77 +               sizeof(CHANNEL_ID_RESUMPTION_MAGIC));
     78 +        signed_data_len += sizeof(CHANNEL_ID_RESUMPTION_MAGIC);
     79 +        memcpy(signed_data + signed_data_len, originalHandshakeHash->data,
     80 +               originalHandshakeHash->len);
     81 +        signed_data_len += originalHandshakeHash->len;
     82 +    }
     83 +    memcpy(signed_data + signed_data_len, hashes.u.raw, hashes.len);
     84 +    signed_data_len += hashes.len;
     85 +
     86 +    rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, signed_data_len);
     87      if (rv != SECSuccess)
     88  	goto loser;
     89  
     90 diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c
     91 index 03cf05c..166022c 100644
     92 --- a/nss/lib/ssl/ssl3ext.c
     93 +++ b/nss/lib/ssl/ssl3ext.c
     94 @@ -812,6 +812,15 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
     95  	return 0;
     96      }
     97  
     98 +    if (ss->sec.ci.sid->cached != never_cached &&
     99 +        ss->sec.ci.sid->u.ssl3.originalHandshakeHash.len == 0) {
    100 +        /* We can't do ChannelID on a connection if we're resuming and didn't
    101 +         * do ChannelID on the original connection: without ChannelID on the
    102 +         * original connection we didn't record the handshake hashes needed for
    103 +         * the signature. */
    104 +	return 0;
    105 +    }
    106 +
    107      if (append) {
    108  	SECStatus rv;
    109  	rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
    110 diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
    111 index 9c789bf..ca68727 100644
    112 --- a/nss/lib/ssl/sslimpl.h
    113 +++ b/nss/lib/ssl/sslimpl.h
    114 @@ -705,6 +705,14 @@ struct sslSessionIDStr {
    115  	     */
    116  	    NewSessionTicket  sessionTicket;
    117              SECItem           srvName;
    118 +
    119 +            /* originalHandshakeHash contains the hash of the original, full
    120 +             * handshake prior to the server's final flow. This is either a
    121 +             * SHA-1/MD5 combination (for TLS < 1.2) or the TLS PRF hash (for
    122 +             * TLS 1.2). This is recorded and used only when ChannelID is
    123 +             * negotiated as it's used to bind the ChannelID signature on the
    124 +             * resumption handshake to the original handshake. */
    125 +	    SECItem           originalHandshakeHash;
    126  	} ssl3;
    127      } u;
    128  };
    129 diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c
    130 index a6f7349..eb5004c 100644
    131 --- a/nss/lib/ssl/sslnonce.c
    132 +++ b/nss/lib/ssl/sslnonce.c
    133 @@ -148,6 +148,9 @@ ssl_DestroySID(sslSessionID *sid)
    134      if (sid->u.ssl3.srvName.data) {
    135  	SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
    136      }
    137 +    if (sid->u.ssl3.originalHandshakeHash.data) {
    138 +	SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
    139 +    }
    140      
    141      PORT_ZFree(sid, sizeof(sslSessionID));
    142  }
    143 diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h
    144 index e4d188f..b813c04 100644
    145 --- a/nss/lib/ssl/sslt.h
    146 +++ b/nss/lib/ssl/sslt.h
    147 @@ -204,7 +204,7 @@ typedef enum {
    148      ssl_app_layer_protocol_xtn       = 16,
    149      ssl_session_ticket_xtn           = 35,
    150      ssl_next_proto_nego_xtn          = 13172,
    151 -    ssl_channel_id_xtn               = 30031,
    152 +    ssl_channel_id_xtn               = 30032,
    153      ssl_padding_xtn                  = 35655,
    154      ssl_renegotiation_info_xtn       = 0xff01	/* experimental number */
    155  } SSLExtensionType;
    156