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,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; | |
OLD | NEW |