OLD | NEW |
(Empty) | |
| 1 diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c |
| 2 index 8b8b758..1c55bc4 100644 |
| 3 --- a/nss/lib/ssl/ssl3con.c |
| 4 +++ b/nss/lib/ssl/ssl3con.c |
| 5 @@ -7570,6 +7570,30 @@ ssl3_SendClientSecondRound(sslSocket *ss) |
| 6 goto loser; /* err code was set. */ |
| 7 } |
| 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 *lastHandshakeHash = &ss->sec.ci.sid->u.ssl3.lastHandshakeHash; |
| 17 + |
| 18 + ssl_GetSpecReadLock(ss); |
| 19 + /* the cwSpec and zero arguments are only used for SSLv3, but we know |
| 20 + * that this connection is not SSLv3 because we negotiated ChannelID. *
/ |
| 21 + PORT_Assert(ss->version > SSL_LIBRARY_VERSION_3_0); |
| 22 + ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0); |
| 23 + ssl_ReleaseSpecReadLock(ss); |
| 24 + |
| 25 + PORT_Assert(lastHandshakeHash->len == 0); |
| 26 + lastHandshakeHash->data = PORT_Alloc(hashes.len); |
| 27 + if (!lastHandshakeHash->data) |
| 28 + goto loser; |
| 29 + lastHandshakeHash->len = hashes.len; |
| 30 + memcpy(lastHandshakeHash->data, hashes.u.raw, hashes.len); |
| 31 + } |
| 32 + |
| 33 ssl_ReleaseXmitBufLock(ss); /*******************************
/ |
| 34 |
| 35 if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) |
| 36 @@ -10568,6 +10592,7 @@ static SECStatus |
| 37 ssl3_SendEncryptedExtensions(sslSocket *ss) |
| 38 { |
| 39 static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature"; |
| 40 + static const char CHANNEL_ID_RESUMPTION_MAGIC[] = "Resumption"; |
| 41 /* This is the ASN.1 prefix for a P-256 public key. Specifically it's: |
| 42 * SEQUENCE |
| 43 * SEQUENCE |
| 44 @@ -10593,7 +10618,10 @@ ssl3_SendEncryptedExtensions(sslSocket *ss) |
| 45 SECItem *spki = NULL; |
| 46 SSL3Hashes hashes; |
| 47 const unsigned char *pub_bytes; |
| 48 - unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + sizeof(SSL3Hashes)]; |
| 49 + unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + |
| 50 + sizeof(CHANNEL_ID_RESUMPTION_MAGIC) + |
| 51 + sizeof(SSL3Hashes)*2]; |
| 52 + size_t j; |
| 53 unsigned char digest[SHA256_LENGTH]; |
| 54 SECItem digest_item; |
| 55 unsigned char signature[64]; |
| 56 @@ -10643,11 +10671,24 @@ ssl3_SendEncryptedExtensions(sslSocket *ss) |
| 57 |
| 58 pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX); |
| 59 |
| 60 - memcpy(signed_data, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC)); |
| 61 - memcpy(signed_data + sizeof(CHANNEL_ID_MAGIC), hashes.u.raw, hashes.len); |
| 62 + j = 0; |
| 63 + memcpy(signed_data + j, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC)); |
| 64 + j += sizeof(CHANNEL_ID_MAGIC); |
| 65 + if (ss->ssl3.hs.isResuming) { |
| 66 + SECItem *lastHandshakeHash = &ss->sec.ci.sid->u.ssl3.lastHandshakeHash; |
| 67 + PORT_Assert(lastHandshakeHash->len > 0); |
| 68 |
| 69 - rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, |
| 70 - sizeof(CHANNEL_ID_MAGIC) + hashes.len); |
| 71 + memcpy(signed_data + j, CHANNEL_ID_RESUMPTION_MAGIC, |
| 72 + sizeof(CHANNEL_ID_RESUMPTION_MAGIC)); |
| 73 + j += sizeof(CHANNEL_ID_RESUMPTION_MAGIC); |
| 74 + memcpy(signed_data + j, lastHandshakeHash->data, |
| 75 + lastHandshakeHash->len); |
| 76 + j += lastHandshakeHash->len; |
| 77 + } |
| 78 + memcpy(signed_data + j, hashes.u.raw, hashes.len); |
| 79 + j += hashes.len; |
| 80 + |
| 81 + rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, j); |
| 82 if (rv != SECSuccess) |
| 83 goto loser; |
| 84 |
| 85 diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c |
| 86 index 0415770..8142c3a 100644 |
| 87 --- a/nss/lib/ssl/ssl3ext.c |
| 88 +++ b/nss/lib/ssl/ssl3ext.c |
| 89 @@ -812,6 +812,15 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append, |
| 90 return 0; |
| 91 } |
| 92 |
| 93 + if (ss->ssl3.hs.isResuming && |
| 94 + ss->sec.ci.sid->u.ssl3.lastHandshakeHash.len == 0) { |
| 95 + /* We can't do ChannelID on a connection if we're resuming and didn't |
| 96 + * do ChannelID on the original connection: without ChannelID on the |
| 97 + * original connection we didn't record the handshake hashes needed for |
| 98 + * the signature. */ |
| 99 + return 0; |
| 100 + } |
| 101 + |
| 102 if (append) { |
| 103 SECStatus rv; |
| 104 rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2); |
| 105 diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h |
| 106 index 614eed1..bc0e85c 100644 |
| 107 --- a/nss/lib/ssl/sslimpl.h |
| 108 +++ b/nss/lib/ssl/sslimpl.h |
| 109 @@ -698,6 +698,14 @@ struct sslSessionIDStr { |
| 110 */ |
| 111 NewSessionTicket sessionTicket; |
| 112 SECItem srvName; |
| 113 + |
| 114 + /* lastHandshakeHash contains the hash of the original, full |
| 115 + * handshake. This is either a SHA-1/MD5 combination (for TLS < |
| 116 + * 1.2) or a SHA-2 hash (for TLS 1.2). This is recorded and used |
| 117 + * only when ChannelID is negotiated as it's used to bind the |
| 118 + * ChannelID signature on the resumption handshake to the original |
| 119 + * handshake. */ |
| 120 + SECItem lastHandshakeHash; |
| 121 } ssl3; |
| 122 } u; |
| 123 }; |
| 124 diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c |
| 125 index a6f7349..a18c4e3 100644 |
| 126 --- a/nss/lib/ssl/sslnonce.c |
| 127 +++ b/nss/lib/ssl/sslnonce.c |
| 128 @@ -148,6 +148,9 @@ ssl_DestroySID(sslSessionID *sid) |
| 129 if (sid->u.ssl3.srvName.data) { |
| 130 SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); |
| 131 } |
| 132 + if (sid->u.ssl3.lastHandshakeHash.data) { |
| 133 + SECITEM_FreeItem(&sid->u.ssl3.lastHandshakeHash, PR_FALSE); |
| 134 + } |
| 135 |
| 136 PORT_ZFree(sid, sizeof(sslSessionID)); |
| 137 } |
| 138 diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h |
| 139 index a8007d8..77ab4b1 100644 |
| 140 --- a/nss/lib/ssl/sslt.h |
| 141 +++ b/nss/lib/ssl/sslt.h |
| 142 @@ -204,7 +204,7 @@ typedef enum { |
| 143 ssl_app_layer_protocol_xtn = 16, |
| 144 ssl_session_ticket_xtn = 35, |
| 145 ssl_next_proto_nego_xtn = 13172, |
| 146 - ssl_channel_id_xtn = 30031, |
| 147 + ssl_channel_id_xtn = 30032, |
| 148 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ |
| 149 } SSLExtensionType; |
| 150 |
OLD | NEW |