1diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c 2index 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 90diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c 91index 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); 110diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h 111index 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 }; 129diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c 130index 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 } 143diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h 144index 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