OLD | NEW |
(Empty) | |
| 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,16 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append, |
| 95 return 0; |
| 96 } |
| 97 |
| 98 + if (ss->ssl3.hs.isResuming && |
| 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 + PORT_Assert(0); |
| 105 + return 0; |
| 106 + } |
| 107 + |
| 108 if (append) { |
| 109 SECStatus rv; |
| 110 rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2); |
| 111 diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h |
| 112 index 9c789bf..ca68727 100644 |
| 113 --- a/nss/lib/ssl/sslimpl.h |
| 114 +++ b/nss/lib/ssl/sslimpl.h |
| 115 @@ -705,6 +705,14 @@ struct sslSessionIDStr { |
| 116 */ |
| 117 NewSessionTicket sessionTicket; |
| 118 SECItem srvName; |
| 119 + |
| 120 + /* originalHandshakeHash contains the hash of the original, full |
| 121 + * handshake prior to the server's final flow. This is either a |
| 122 + * SHA-1/MD5 combination (for TLS < 1.2) or the TLS PRF hash (for |
| 123 + * TLS 1.2). This is recorded and used only when ChannelID is |
| 124 + * negotiated as it's used to bind the ChannelID signature on the |
| 125 + * resumption handshake to the original handshake. */ |
| 126 + SECItem originalHandshakeHash; |
| 127 } ssl3; |
| 128 } u; |
| 129 }; |
| 130 diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c |
| 131 index a6f7349..eb5004c 100644 |
| 132 --- a/nss/lib/ssl/sslnonce.c |
| 133 +++ b/nss/lib/ssl/sslnonce.c |
| 134 @@ -148,6 +148,9 @@ ssl_DestroySID(sslSessionID *sid) |
| 135 if (sid->u.ssl3.srvName.data) { |
| 136 SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); |
| 137 } |
| 138 + if (sid->u.ssl3.originalHandshakeHash.data) { |
| 139 + SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); |
| 140 + } |
| 141 |
| 142 PORT_ZFree(sid, sizeof(sslSessionID)); |
| 143 } |
| 144 diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h |
| 145 index e4d188f..b813c04 100644 |
| 146 --- a/nss/lib/ssl/sslt.h |
| 147 +++ b/nss/lib/ssl/sslt.h |
| 148 @@ -204,7 +204,7 @@ typedef enum { |
| 149 ssl_app_layer_protocol_xtn = 16, |
| 150 ssl_session_ticket_xtn = 35, |
| 151 ssl_next_proto_nego_xtn = 13172, |
| 152 - ssl_channel_id_xtn = 30031, |
| 153 + ssl_channel_id_xtn = 30032, |
| 154 ssl_padding_xtn = 35655, |
| 155 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ |
| 156 } SSLExtensionType; |
OLD | NEW |