OLD | NEW |
(Empty) | |
| 1 Index: net/third_party/nss/ssl/sslt.h |
| 2 =================================================================== |
| 3 --- net/third_party/nss/ssl/sslt.h (revision 202696) |
| 4 +++ net/third_party/nss/ssl/sslt.h (working copy) |
| 5 @@ -193,6 +193,7 @@ |
| 6 ssl_elliptic_curves_xtn = 10, |
| 7 ssl_ec_point_formats_xtn = 11, |
| 8 #endif |
| 9 + ssl_signature_algorithms_xtn = 13, |
| 10 ssl_use_srtp_xtn = 14, |
| 11 ssl_session_ticket_xtn = 35, |
| 12 ssl_next_proto_nego_xtn = 13172, |
| 13 @@ -200,6 +201,6 @@ |
| 14 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ |
| 15 } SSLExtensionType; |
| 16 |
| 17 -#define SSL_MAX_EXTENSIONS 9 |
| 18 +#define SSL_MAX_EXTENSIONS 10 |
| 19 |
| 20 #endif /* __sslt_h_ */ |
| 21 Index: net/third_party/nss/ssl/sslproto.h |
| 22 =================================================================== |
| 23 --- net/third_party/nss/ssl/sslproto.h (revision 202696) |
| 24 +++ net/third_party/nss/ssl/sslproto.h (working copy) |
| 25 @@ -16,6 +16,7 @@ |
| 26 #define SSL_LIBRARY_VERSION_3_0 0x0300 |
| 27 #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301 |
| 28 #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302 |
| 29 +#define SSL_LIBRARY_VERSION_TLS_1_2 0x0303 |
| 30 /* Note: this is the internal format, not the wire format */ |
| 31 #define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302 |
| 32 |
| 33 Index: net/third_party/nss/ssl/SSLerrs.h |
| 34 =================================================================== |
| 35 --- net/third_party/nss/ssl/SSLerrs.h (revision 202696) |
| 36 +++ net/third_party/nss/ssl/SSLerrs.h (working copy) |
| 37 @@ -412,3 +412,12 @@ |
| 38 |
| 39 ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 128), |
| 40 "The application could not get a TLS Channel ID.") |
| 41 + |
| 42 +ER3(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM, (SSL_ERROR_BASE + 129), |
| 43 +"Unsupported hash algorithm used by TLS peer.") |
| 44 + |
| 45 +ER3(SSL_ERROR_DIGEST_FAILURE, (SSL_ERROR_BASE + 130), |
| 46 +"Digest function failed.") |
| 47 + |
| 48 +ER3(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 131), |
| 49 +"Incorrect signature algorithm specified in a digitally-signed element.") |
| 50 Index: net/third_party/nss/ssl/sslerr.h |
| 51 =================================================================== |
| 52 --- net/third_party/nss/ssl/sslerr.h (revision 202696) |
| 53 +++ net/third_party/nss/ssl/sslerr.h (working copy) |
| 54 @@ -194,6 +194,10 @@ |
| 55 SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 127), |
| 56 SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 128), |
| 57 |
| 58 +SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 129), |
| 59 +SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 130), |
| 60 +SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 131), |
| 61 + |
| 62 SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ |
| 63 } SSLErrorCodes; |
| 64 #endif /* NO_SECURITY_ERROR_ENUM */ |
| 65 Index: net/third_party/nss/ssl/sslimpl.h |
| 66 =================================================================== |
| 67 --- net/third_party/nss/ssl/sslimpl.h (revision 202696) |
| 68 +++ net/third_party/nss/ssl/sslimpl.h (working copy) |
| 69 @@ -799,6 +799,7 @@ |
| 70 PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS]; |
| 71 PK11Context * md5; /* handshake running hashes */ |
| 72 PK11Context * sha; |
| 73 + PK11Context * tls12_handshake_hash; |
| 74 const ssl3KEADef * kea_def; |
| 75 ssl3CipherSuite cipher_suite; |
| 76 const ssl3CipherSuiteDef *suite_def; |
| 77 @@ -820,7 +821,7 @@ |
| 78 PRUint16 finishedBytes; /* size of single finished below */ |
| 79 union { |
| 80 TLSFinished tFinished[2]; /* client, then server */ |
| 81 - SSL3Hashes sFinished[2]; |
| 82 + SSL3Finished sFinished[2]; |
| 83 SSL3Opaque data[72]; |
| 84 } finishedMsgs; |
| 85 #ifdef NSS_ENABLE_ECC |
| 86 @@ -835,6 +836,12 @@ |
| 87 /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */ |
| 88 PRBool cacheSID; |
| 89 |
| 90 + /* clientSigAndHash contains the contents of the signature_algorithms |
| 91 + * extension (if any) from the client. This is only valid for TLS 1.2 |
| 92 + * or later. */ |
| 93 + SSL3SignatureAndHashAlgorithm *clientSigAndHash; |
| 94 + unsigned int numClientSigAndHash; |
| 95 + |
| 96 /* This group of values is used for DTLS */ |
| 97 PRUint16 sendMessageSeq; /* The sending message sequence |
| 98 * number */ |
| 99 @@ -1473,7 +1480,7 @@ |
| 100 * runtime to determine which versions are supported by the version of libssl |
| 101 * in use. |
| 102 */ |
| 103 -#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_1 |
| 104 +#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_2 |
| 105 |
| 106 /* Rename this macro SSL_ALL_VERSIONS_DISABLED when SSL 2.0 is removed. */ |
| 107 #define SSL3_ALL_VERSIONS_DISABLED(vrange) \ |
| 108 @@ -1639,10 +1646,12 @@ |
| 109 SSL3Opaque *b, PRUint32 length, |
| 110 SECKEYPublicKey *srvrPubKey, |
| 111 SECKEYPrivateKey *srvrPrivKey); |
| 112 -extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss); |
| 113 +extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss, |
| 114 + const SSL3SignatureAndHashAlgorithm *sigAndHash); |
| 115 #endif |
| 116 |
| 117 -extern SECStatus ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf, |
| 118 +extern SECStatus ssl3_ComputeCommonKeyHash(SECOidTag hashAlg, |
| 119 + PRUint8 * hashBuf, |
| 120 unsigned int bufLen, SSL3Hashes *hashes, |
| 121 PRBool bypassPKCS11); |
| 122 extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName); |
| 123 @@ -1655,12 +1664,21 @@ |
| 124 PRInt32 lenSize); |
| 125 extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss, |
| 126 const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize); |
| 127 +extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(sslSocket *ss, |
| 128 + const SSL3SignatureAndHashAlgorithm* sigAndHash); |
| 129 extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, |
| 130 SSL3Opaque **b, PRUint32 *length); |
| 131 extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, |
| 132 SSL3Opaque **b, PRUint32 *length); |
| 133 extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, |
| 134 PRInt32 bytes, SSL3Opaque **b, PRUint32 *length); |
| 135 +extern SECOidTag ssl3_TLSHashAlgorithmToOID(int hashFunc); |
| 136 +extern SECStatus ssl3_CheckSignatureAndHashAlgorithmConsistency( |
| 137 + const SSL3SignatureAndHashAlgorithm *sigAndHash, |
| 138 + CERTCertificate* cert); |
| 139 +extern SECStatus ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss, |
| 140 + SSL3Opaque **b, PRUint32 *length, |
| 141 + SSL3SignatureAndHashAlgorithm *out); |
| 142 extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, |
| 143 SECItem *buf, PRBool isTLS); |
| 144 extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash, |
| 145 Index: net/third_party/nss/ssl/ssl3prot.h |
| 146 =================================================================== |
| 147 --- net/third_party/nss/ssl/ssl3prot.h (revision 202696) |
| 148 +++ net/third_party/nss/ssl/ssl3prot.h (working copy) |
| 149 @@ -212,11 +212,51 @@ |
| 150 } u; |
| 151 } SSL3ServerParams; |
| 152 |
| 153 +/* This enum reflects HashAlgorithm enum from |
| 154 + * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 |
| 155 + * |
| 156 + * When updating, be sure to also update ssl3_TLSHashAlgorithmToOID. */ |
| 157 +enum { |
| 158 + tls_hash_md5 = 1, |
| 159 + tls_hash_sha1 = 2, |
| 160 + tls_hash_sha224 = 3, |
| 161 + tls_hash_sha256 = 4, |
| 162 + tls_hash_sha384 = 5, |
| 163 + tls_hash_sha512 = 6 |
| 164 +}; |
| 165 + |
| 166 +/* This enum reflects SignatureAlgorithm enum from |
| 167 + * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 168 +typedef enum { |
| 169 + tls_sig_rsa = 1, |
| 170 + tls_sig_dsa = 2, |
| 171 + tls_sig_ecdsa = 3 |
| 172 +} TLSSignatureAlgorithm; |
| 173 + |
| 174 typedef struct { |
| 175 + SECOidTag hashAlg; |
| 176 + TLSSignatureAlgorithm sigAlg; |
| 177 +} SSL3SignatureAndHashAlgorithm; |
| 178 + |
| 179 +/* SSL3HashesIndividually contains a combination MD5/SHA1 hash, as used in TLS |
| 180 + * prior to 1.2. */ |
| 181 +typedef struct { |
| 182 uint8 md5[16]; |
| 183 uint8 sha[20]; |
| 184 +} SSL3HashesIndividually; |
| 185 + |
| 186 +/* SSL3Hashes contains an SSL hash value. The digest is contained in |u.raw| |
| 187 + * which, if |hashAlg==SEC_OID_UNKNOWN| is also a SSL3HashesIndividually |
| 188 + * struct. */ |
| 189 +typedef struct { |
| 190 + unsigned int len; |
| 191 + SECOidTag hashAlg; |
| 192 + union { |
| 193 + PRUint8 raw[64]; |
| 194 + SSL3HashesIndividually s; |
| 195 + } u; |
| 196 } SSL3Hashes; |
| 197 - |
| 198 + |
| 199 typedef struct { |
| 200 union { |
| 201 SSL3Opaque anonymous; |
| 202 @@ -274,7 +314,7 @@ |
| 203 sender_server = 0x53525652 |
| 204 } SSL3Sender; |
| 205 |
| 206 -typedef SSL3Hashes SSL3Finished; |
| 207 +typedef SSL3HashesIndividually SSL3Finished; |
| 208 |
| 209 typedef struct { |
| 210 SSL3Opaque verify_data[12]; |
| 211 Index: net/third_party/nss/ssl/ssl3ecc.c |
| 212 =================================================================== |
| 213 --- net/third_party/nss/ssl/ssl3ecc.c (revision 202696) |
| 214 +++ net/third_party/nss/ssl/ssl3ecc.c (working copy) |
| 215 @@ -217,9 +223,10 @@ |
| 216 |
| 217 /* Caller must set hiLevel error code. */ |
| 218 static SECStatus |
| 219 -ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint, |
| 220 - SSL3Random *client_rand, SSL3Random *server_rand, |
| 221 - SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 222 +ssl3_ComputeECDHKeyHash(SECOidTag hashAlg, |
| 223 + SECItem ec_params, SECItem server_ecpoint, |
| 224 + SSL3Random *client_rand, SSL3Random *server_rand, |
| 225 + SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 226 { |
| 227 PRUint8 * hashBuf; |
| 228 PRUint8 * pBuf; |
| 229 @@ -255,11 +262,14 @@ |
| 230 pBuf += server_ecpoint.len; |
| 231 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); |
| 232 |
| 233 - rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11); |
| 234 + rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, |
| 235 + bypassPKCS11); |
| 236 |
| 237 PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen)); |
| 238 - PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH)); |
| 239 - PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH)
); |
| 240 + PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", |
| 241 + hashes->u.s.md5, MD5_LENGTH)); |
| 242 + PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", |
| 243 + hashes->u.s.sha, SHA1_LENGTH)); |
| 244 |
| 245 if (hashBuf != buf) |
| 246 PORT_Free(hashBuf); |
| 247 @@ -273,7 +283,7 @@ |
| 248 { |
| 249 PK11SymKey * pms = NULL; |
| 250 SECStatus rv = SECFailure; |
| 251 - PRBool isTLS; |
| 252 + PRBool isTLS, isTLS12; |
| 253 CK_MECHANISM_TYPE target; |
| 254 SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */ |
| 255 SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */ |
| 256 @@ -282,6 +292,7 @@ |
| 257 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 258 |
| 259 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 260 + isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2)
; |
| 261 |
| 262 /* Generate ephemeral EC keypair */ |
| 263 if (svrPubKey->keyType != ecKey) { |
| 264 @@ -300,8 +311,13 @@ |
| 265 pubKey->u.ec.publicValue.data, |
| 266 pubKey->u.ec.publicValue.len)); |
| 267 |
| 268 - if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 269 - else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 270 + if (isTLS12) { |
| 271 + target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
| 272 + } else if (isTLS) { |
| 273 + target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 274 + } else { |
| 275 + target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 276 + } |
| 277 |
| 278 /* Determine the PMS */ |
| 279 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, |
| 280 @@ -365,7 +381,7 @@ |
| 281 SECStatus rv; |
| 282 SECKEYPublicKey clntPubKey; |
| 283 CK_MECHANISM_TYPE target; |
| 284 - PRBool isTLS; |
| 285 + PRBool isTLS, isTLS12; |
| 286 |
| 287 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 288 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 289 @@ -384,9 +400,15 @@ |
| 290 } |
| 291 |
| 292 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 293 + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2)
; |
| 294 |
| 295 - if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 296 - else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 297 + if (isTLS12) { |
| 298 + target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
| 299 + } else if (isTLS) { |
| 300 + target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 301 + } else { |
| 302 + target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 303 + } |
| 304 |
| 305 /* Determine the PMS */ |
| 306 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, |
| 307 @@ -582,7 +604,7 @@ |
| 308 { |
| 309 PRArenaPool * arena = NULL; |
| 310 SECKEYPublicKey *peerKey = NULL; |
| 311 - PRBool isTLS; |
| 312 + PRBool isTLS, isTLS12; |
| 313 SECStatus rv; |
| 314 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH; |
| 315 SSL3AlertDescription desc = illegal_parameter; |
| 316 @@ -592,8 +614,12 @@ |
| 317 SECItem ec_params = {siBuffer, NULL, 0}; |
| 318 SECItem ec_point = {siBuffer, NULL, 0}; |
| 319 unsigned char paramBuf[3]; /* only for curve_type == named_curve */ |
| 320 + SSL3SignatureAndHashAlgorithm sigAndHash; |
| 321 |
| 322 + sigAndHash.hashAlg = SEC_OID_UNKNOWN; |
| 323 + |
| 324 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 325 + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2)
; |
| 326 |
| 327 /* XXX This works only for named curves, revisit this when |
| 328 * we support generic curves. |
| 329 @@ -625,6 +651,19 @@ |
| 330 goto alert_loser; |
| 331 } |
| 332 |
| 333 + if (isTLS12) { |
| 334 + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
| 335 + &sigAndHash); |
| 336 + if (rv != SECSuccess) { |
| 337 + goto loser; /* malformed or unsupported. */ |
| 338 + } |
| 339 + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
| 340 + &sigAndHash, ss->sec.peerCert); |
| 341 + if (rv != SECSuccess) { |
| 342 + goto loser; |
| 343 + } |
| 344 + } |
| 345 + |
| 346 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
| 347 if (rv != SECSuccess) { |
| 348 goto loser; /* malformed. */ |
| 349 @@ -647,10 +686,10 @@ |
| 350 /* |
| 351 * check to make sure the hash is signed by right guy |
| 352 */ |
| 353 - rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point, |
| 354 - &ss->ssl3.hs.client_random, |
| 355 - &ss->ssl3.hs.server_random, |
| 356 - &hashes, ss->opt.bypassPKCS11); |
| 357 + rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point, |
| 358 + &ss->ssl3.hs.client_random, |
| 359 + &ss->ssl3.hs.server_random, |
| 360 + &hashes, ss->opt.bypassPKCS11); |
| 361 |
| 362 if (rv != SECSuccess) { |
| 363 errCode = |
| 364 @@ -714,12 +753,14 @@ |
| 365 } |
| 366 |
| 367 SECStatus |
| 368 -ssl3_SendECDHServerKeyExchange(sslSocket *ss) |
| 369 +ssl3_SendECDHServerKeyExchange( |
| 370 + sslSocket *ss, |
| 371 + const SSL3SignatureAndHashAlgorithm *sigAndHash) |
| 372 { |
| 373 -const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
| 374 + const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
| 375 SECStatus rv = SECFailure; |
| 376 int length; |
| 377 - PRBool isTLS; |
| 378 + PRBool isTLS, isTLS12; |
| 379 SECItem signed_hash = {siBuffer, NULL, 0}; |
| 380 SSL3Hashes hashes; |
| 381 |
| 382 @@ -729,7 +770,6 @@ |
| 383 ECName curve; |
| 384 SSL3KEAType certIndex; |
| 385 |
| 386 - |
| 387 /* Generate ephemeral ECDH key pair and send the public key */ |
| 388 curve = ssl3_GetCurveNameForServerSocket(ss); |
| 389 if (curve == ec_noName) { |
| 390 @@ -758,16 +798,19 @@ |
| 391 goto loser; |
| 392 } |
| 393 |
| 394 - rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue, |
| 395 - &ss->ssl3.hs.client_random, |
| 396 - &ss->ssl3.hs.server_random, |
| 397 - &hashes, ss->opt.bypassPKCS11); |
| 398 + rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg, |
| 399 + ec_params, |
| 400 + ecdhePub->u.ec.publicValue, |
| 401 + &ss->ssl3.hs.client_random, |
| 402 + &ss->ssl3.hs.server_random, |
| 403 + &hashes, ss->opt.bypassPKCS11); |
| 404 if (rv != SECSuccess) { |
| 405 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 406 goto loser; |
| 407 } |
| 408 |
| 409 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 410 + isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2)
; |
| 411 |
| 412 /* XXX SSLKEAType isn't really a good choice for |
| 413 * indexing certificates but that's all we have |
| 414 @@ -791,7 +834,7 @@ |
| 415 |
| 416 length = ec_params.len + |
| 417 1 + ecdhePub->u.ec.publicValue.len + |
| 418 - 2 + signed_hash.len; |
| 419 + (isTLS12 ? 2 : 0) + 2 + signed_hash.len; |
| 420 |
| 421 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); |
| 422 if (rv != SECSuccess) { |
| 423 @@ -809,6 +852,13 @@ |
| 424 goto loser; /* err set by AppendHandshake. */ |
| 425 } |
| 426 |
| 427 + if (isTLS12) { |
| 428 + rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash); |
| 429 + if (rv != SECSuccess) { |
| 430 + goto loser; /* err set by AppendHandshake. */ |
| 431 + } |
| 432 + } |
| 433 + |
| 434 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, |
| 435 signed_hash.len, 2); |
| 436 if (rv != SECSuccess) { |
| 437 Index: net/third_party/nss/ssl/ssl3ext.c |
| 438 =================================================================== |
| 439 --- net/third_party/nss/ssl/ssl3ext.c (revision 202696) |
| 440 +++ net/third_party/nss/ssl/ssl3ext.c (working copy) |
| 441 @@ -74,6 +74,10 @@ |
| 442 SECItem *data); |
| 443 static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, |
| 444 PRUint32 maxBytes); |
| 445 +static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, |
| 446 + PRUint32 maxBytes); |
| 447 +static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, |
| 448 + SECItem *data); |
| 449 |
| 450 /* |
| 451 * Write bytes. Using this function means the SECItem structure |
| 452 @@ -236,6 +240,7 @@ |
| 453 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
| 454 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, |
| 455 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, |
| 456 + { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, |
| 457 { -1, NULL } |
| 458 }; |
| 459 |
| 460 @@ -276,7 +281,8 @@ |
| 461 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, |
| 462 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, |
| 463 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, |
| 464 - { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } |
| 465 + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, |
| 466 + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn } |
| 467 /* any extra entries will appear as { 0, NULL } */ |
| 468 }; |
| 469 |
| 470 @@ -2039,3 +2045,134 @@ |
| 471 return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn, |
| 472 ssl3_SendUseSRTPXtn); |
| 473 } |
| 474 + |
| 475 +/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension |
| 476 + * from a client. |
| 477 + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 478 +static SECStatus |
| 479 +ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) |
| 480 +{ |
| 481 + SECStatus rv; |
| 482 + SECItem algorithms; |
| 483 + const unsigned char *b; |
| 484 + unsigned int numAlgorithms, i; |
| 485 + |
| 486 + /* Ignore this extension if we aren't doing TLS 1.2 or greater. */ |
| 487 + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { |
| 488 + return SECSuccess; |
| 489 + } |
| 490 + |
| 491 + /* Keep track of negotiated extensions. */ |
| 492 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 493 + |
| 494 + rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data, |
| 495 + &data->len); |
| 496 + if (rv != SECSuccess) { |
| 497 + return SECFailure; |
| 498 + } |
| 499 + /* Trailing data or odd-length parameters is invalid. */ |
| 500 + if (data->len != 0 || (algorithms.len & 1) != 0) { |
| 501 + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); |
| 502 + return SECFailure; |
| 503 + } |
| 504 + |
| 505 + numAlgorithms = algorithms.len/2; |
| 506 + |
| 507 + if (numAlgorithms == 0) { |
| 508 + return SECSuccess; |
| 509 + } |
| 510 + /* We don't care to process excessive numbers of algorithms. */ |
| 511 + if (numAlgorithms > 512) { |
| 512 + numAlgorithms = 512; |
| 513 + } |
| 514 + |
| 515 + ss->ssl3.hs.clientSigAndHash = |
| 516 + PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms); |
| 517 + if (!ss->ssl3.hs.clientSigAndHash) { |
| 518 + return SECFailure; |
| 519 + } |
| 520 + ss->ssl3.hs.numClientSigAndHash = 0; |
| 521 + |
| 522 + b = algorithms.data; |
| 523 + for (i = 0; i < numAlgorithms; i++) { |
| 524 + unsigned char tls_hash = *(b++); |
| 525 + unsigned char tls_sig = *(b++); |
| 526 + SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash); |
| 527 + |
| 528 + if (hash == SEC_OID_UNKNOWN) { |
| 529 + /* We ignore formats that we don't understand. */ |
| 530 + continue; |
| 531 + } |
| 532 + /* tls_sig support will be checked later in |
| 533 + * ssl3_PickSignatureHashAlgorithm. */ |
| 534 + ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash; |
| 535 + ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig; |
| 536 + ss->ssl3.hs.numClientSigAndHash++; |
| 537 + } |
| 538 + |
| 539 + if (!ss->ssl3.hs.numClientSigAndHash) { |
| 540 + /* We didn't understand any of the client's requested signature |
| 541 + * formats. We'll use the defaults. */ |
| 542 + PORT_Free(ss->ssl3.hs.clientSigAndHash); |
| 543 + ss->ssl3.hs.clientSigAndHash = NULL; |
| 544 + } |
| 545 + |
| 546 + return SECSuccess; |
| 547 +} |
| 548 + |
| 549 +/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS |
| 550 + * 1.2 ClientHellos. */ |
| 551 +static PRInt32 |
| 552 +ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) |
| 553 +{ |
| 554 + static const unsigned char signatureAlgorithms[] = { |
| 555 + /* This block is the contents of our signature_algorithms extension, in |
| 556 + * wire format. See |
| 557 + * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 558 + tls_hash_sha256, tls_sig_rsa, |
| 559 + tls_hash_sha384, tls_sig_rsa, |
| 560 + tls_hash_sha1, tls_sig_rsa, |
| 561 +#ifdef NSS_ENABLE_ECC |
| 562 + tls_hash_sha256, tls_sig_ecdsa, |
| 563 + tls_hash_sha384, tls_sig_ecdsa, |
| 564 + tls_hash_sha1, tls_sig_ecdsa, |
| 565 +#endif |
| 566 + tls_hash_sha256, tls_sig_dsa, |
| 567 + tls_hash_sha1, tls_sig_dsa, |
| 568 + }; |
| 569 + PRInt32 extension_length; |
| 570 + |
| 571 + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { |
| 572 + return 0; |
| 573 + } |
| 574 + |
| 575 + extension_length = |
| 576 + 2 /* extension type */ + |
| 577 + 2 /* extension length */ + |
| 578 + 2 /* supported_signature_algorithms length */ + |
| 579 + sizeof(signatureAlgorithms); |
| 580 + |
| 581 + if (append && maxBytes >= extension_length) { |
| 582 + SECStatus rv; |
| 583 + rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); |
| 584 + if (rv != SECSuccess) |
| 585 + goto loser; |
| 586 + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); |
| 587 + if (rv != SECSuccess) |
| 588 + goto loser; |
| 589 + rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms, |
| 590 + sizeof(signatureAlgorithms), 2); |
| 591 + if (rv != SECSuccess) |
| 592 + goto loser; |
| 593 + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
| 594 + ssl_signature_algorithms_xtn; |
| 595 + } else if (maxBytes < extension_length) { |
| 596 + PORT_Assert(0); |
| 597 + return 0; |
| 598 + } |
| 599 + |
| 600 + return extension_length; |
| 601 + |
| 602 +loser: |
| 603 + return -1; |
| 604 +} |
| 605 Index: net/third_party/nss/ssl/sslsock.c |
| 606 =================================================================== |
| 607 --- net/third_party/nss/ssl/sslsock.c (revision 202696) |
| 608 +++ net/third_party/nss/ssl/sslsock.c (working copy) |
| 609 @@ -782,6 +789,17 @@ |
| 610 rv = SECFailure; |
| 611 } else { |
| 612 if (PR_FALSE != on) { |
| 613 + /* TLS 1.2 isn't supported in bypass mode. */ |
| 614 + if (ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_2) { |
| 615 + /* If the user requested a minimum version of TLS 1.2 then |
| 616 + * we don't silently downgrade. */ |
| 617 + PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE); |
| 618 + rv = SECFailure; |
| 619 + break; |
| 620 + } |
| 621 + if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_2) { |
| 622 + ss->vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; |
| 623 + } |
| 624 if (PR_SUCCESS == SSL_BypassSetup() ) { |
| 625 #ifdef NO_PKCS11_BYPASS |
| 626 ss->opt.bypassPKCS11 = PR_FALSE; |
| 627 Index: net/third_party/nss/ssl/ssl3con.c |
| 628 =================================================================== |
| 629 --- net/third_party/nss/ssl/ssl3con.c (revision 202696) |
| 630 +++ net/third_party/nss/ssl/ssl3con.c (working copy) |
| 631 @@ -15,6 +15,7 @@ |
| 632 #include "keyhi.h" |
| 633 #include "secder.h" |
| 634 #include "secitem.h" |
| 635 +#include "sechash.h" |
| 636 |
| 637 #include "sslimpl.h" |
| 638 #include "sslproto.h" |
| 639 @@ -64,6 +74,7 @@ |
| 640 const unsigned char *b, |
| 641 unsigned int l); |
| 642 static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); |
| 643 +static int ssl3_OIDToTLSHashAlgorithm(SECOidTag oid); |
| 644 |
| 645 static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, |
| 646 int maxOutputLen, const unsigned char *input, |
| 647 @@ -811,32 +822,36 @@ |
| 648 SECItem hashItem; |
| 649 |
| 650 buf->data = NULL; |
| 651 - signatureLen = PK11_SignatureLen(key); |
| 652 - if (signatureLen <= 0) { |
| 653 - PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 654 - goto done; |
| 655 - } |
| 656 |
| 657 - buf->len = (unsigned)signatureLen; |
| 658 - buf->data = (unsigned char *)PORT_Alloc(signatureLen); |
| 659 - if (!buf->data) |
| 660 - goto done; /* error code was set. */ |
| 661 - |
| 662 switch (key->keyType) { |
| 663 case rsaKey: |
| 664 - hashItem.data = hash->md5; |
| 665 - hashItem.len = sizeof(SSL3Hashes); |
| 666 + hashItem.data = hash->u.raw; |
| 667 + hashItem.len = hash->len; |
| 668 break; |
| 669 case dsaKey: |
| 670 doDerEncode = isTLS; |
| 671 - hashItem.data = hash->sha; |
| 672 - hashItem.len = sizeof(hash->sha); |
| 673 + /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
| 674 + * In that case, we use just the SHA1 part. */ |
| 675 + if (hash->hashAlg == SEC_OID_UNKNOWN) { |
| 676 + hashItem.data = hash->u.s.sha; |
| 677 + hashItem.len = sizeof(hash->u.s.sha); |
| 678 + } else { |
| 679 + hashItem.data = hash->u.raw; |
| 680 + hashItem.len = hash->len; |
| 681 + } |
| 682 break; |
| 683 #ifdef NSS_ENABLE_ECC |
| 684 case ecKey: |
| 685 doDerEncode = PR_TRUE; |
| 686 - hashItem.data = hash->sha; |
| 687 - hashItem.len = sizeof(hash->sha); |
| 688 + /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
| 689 + * In that case, we use just the SHA1 part. */ |
| 690 + if (hash->hashAlg == SEC_OID_UNKNOWN) { |
| 691 + hashItem.data = hash->u.s.sha; |
| 692 + hashItem.len = sizeof(hash->u.s.sha); |
| 693 + } else { |
| 694 + hashItem.data = hash->u.raw; |
| 695 + hashItem.len = hash->len; |
| 696 + } |
| 697 break; |
| 698 #endif /* NSS_ENABLE_ECC */ |
| 699 default: |
| 700 @@ -845,7 +860,22 @@ |
| 701 } |
| 702 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len))
; |
| 703 |
| 704 - rv = PK11_Sign(key, buf, &hashItem); |
| 705 + if (hash->hashAlg == SEC_OID_UNKNOWN) { |
| 706 + signatureLen = PK11_SignatureLen(key); |
| 707 + if (signatureLen <= 0) { |
| 708 + PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 709 + goto done; |
| 710 + } |
| 711 + |
| 712 + buf->len = (unsigned)signatureLen; |
| 713 + buf->data = (unsigned char *)PORT_Alloc(signatureLen); |
| 714 + if (!buf->data) |
| 715 + goto done; /* error code was set. */ |
| 716 + |
| 717 + rv = PK11_Sign(key, buf, &hashItem); |
| 718 + } else { |
| 719 + rv = SGN_Digest(key, hash->hashAlg, buf, &hashItem); |
| 720 + } |
| 721 if (rv != SECSuccess) { |
| 722 ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE); |
| 723 } else if (doDerEncode) { |
| 724 @@ -879,9 +909,8 @@ |
| 725 SECItem * signature = NULL; |
| 726 SECStatus rv; |
| 727 SECItem hashItem; |
| 728 -#ifdef NSS_ENABLE_ECC |
| 729 - unsigned int len; |
| 730 -#endif /* NSS_ENABLE_ECC */ |
| 731 + SECOidTag encAlg; |
| 732 + SECOidTag hashAlg; |
| 733 |
| 734 |
| 735 PRINT_BUF(60, (NULL, "check signed hashes", |
| 736 @@ -893,14 +922,24 @@ |
| 737 return SECFailure; |
| 738 } |
| 739 |
| 740 + hashAlg = hash->hashAlg; |
| 741 switch (key->keyType) { |
| 742 case rsaKey: |
| 743 - hashItem.data = hash->md5; |
| 744 - hashItem.len = sizeof(SSL3Hashes); |
| 745 + encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION; |
| 746 + hashItem.data = hash->u.raw; |
| 747 + hashItem.len = hash->len; |
| 748 break; |
| 749 case dsaKey: |
| 750 - hashItem.data = hash->sha; |
| 751 - hashItem.len = sizeof(hash->sha); |
| 752 + encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; |
| 753 + /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
| 754 + * In that case, we use just the SHA1 part. */ |
| 755 + if (hash->hashAlg == SEC_OID_UNKNOWN) { |
| 756 + hashItem.data = hash->u.s.sha; |
| 757 + hashItem.len = sizeof(hash->u.s.sha); |
| 758 + } else { |
| 759 + hashItem.data = hash->u.raw; |
| 760 + hashItem.len = hash->len; |
| 761 + } |
| 762 /* Allow DER encoded DSA signatures in SSL 3.0 */ |
| 763 if (isTLS || buf->len != SECKEY_SignatureLen(key)) { |
| 764 signature = DSAU_DecodeDerSig(buf); |
| 765 @@ -914,25 +953,21 @@ |
| 766 |
| 767 #ifdef NSS_ENABLE_ECC |
| 768 case ecKey: |
| 769 - hashItem.data = hash->sha; |
| 770 - hashItem.len = sizeof(hash->sha); |
| 771 - /* |
| 772 - * ECDSA signatures always encode the integers r and s |
| 773 - * using ASN (unlike DSA where ASN encoding is used |
| 774 - * with TLS but not with SSL3) |
| 775 + encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; |
| 776 + /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
| 777 + * In that case, we use just the SHA1 part. |
| 778 + * ECDSA signatures always encode the integers r and s using ASN.1 |
| 779 + * (unlike DSA where ASN.1 encoding is used with TLS but not with |
| 780 + * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA. |
| 781 */ |
| 782 - len = SECKEY_SignatureLen(key); |
| 783 - if (len == 0) { |
| 784 - SECKEY_DestroyPublicKey(key); |
| 785 - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); |
| 786 - return SECFailure; |
| 787 + if (hash->hashAlg == SEC_OID_UNKNOWN) { |
| 788 + hashAlg = SEC_OID_SHA1; |
| 789 + hashItem.data = hash->u.s.sha; |
| 790 + hashItem.len = sizeof(hash->u.s.sha); |
| 791 + } else { |
| 792 + hashItem.data = hash->u.raw; |
| 793 + hashItem.len = hash->len; |
| 794 } |
| 795 - signature = DSAU_DecodeDerSigToLen(buf, len); |
| 796 - if (!signature) { |
| 797 - PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
| 798 - return SECFailure; |
| 799 - } |
| 800 - buf = signature; |
| 801 break; |
| 802 #endif /* NSS_ENABLE_ECC */ |
| 803 |
| 804 @@ -945,7 +980,17 @@ |
| 805 PRINT_BUF(60, (NULL, "hash(es) to be verified", |
| 806 hashItem.data, hashItem.len)); |
| 807 |
| 808 - rv = PK11_Verify(key, buf, &hashItem, pwArg); |
| 809 + if (hashAlg == SEC_OID_UNKNOWN || key->keyType == dsaKey) { |
| 810 + /* VFY_VerifyDigestDirect requires DSA signatures to be DER-encoded. |
| 811 + * DSA signatures are DER-encoded in TLS but not in SSL3 and the code |
| 812 + * above always removes the DER encoding of DSA signatures when |
| 813 + * present. Thus DSA signatures are always verified with PK11_Verify. |
| 814 + */ |
| 815 + rv = PK11_Verify(key, buf, &hashItem, pwArg); |
| 816 + } else { |
| 817 + rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg, |
| 818 + pwArg); |
| 819 + } |
| 820 SECKEY_DestroyPublicKey(key); |
| 821 if (signature) { |
| 822 SECITEM_FreeItem(signature, PR_TRUE); |
| 823 @@ -961,33 +1006,69 @@ |
| 824 /* Called from ssl3_ComputeExportRSAKeyHash |
| 825 * ssl3_ComputeDHKeyHash |
| 826 * which are called from ssl3_HandleServerKeyExchange. |
| 827 + * |
| 828 + * hashAlg: either the OID for a hash algorithm or SEC_OID_UNKNOWN to specify |
| 829 + * the pre-1.2, MD5/SHA1 combination hash. |
| 830 */ |
| 831 SECStatus |
| 832 -ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf, unsigned int bufLen, |
| 833 - SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 834 +ssl3_ComputeCommonKeyHash(SECOidTag hashAlg, |
| 835 + PRUint8 * hashBuf, unsigned int bufLen, |
| 836 + SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 837 { |
| 838 SECStatus rv = SECSuccess; |
| 839 |
| 840 #ifndef NO_PKCS11_BYPASS |
| 841 if (bypassPKCS11) { |
| 842 - MD5_HashBuf (hashes->md5, hashBuf, bufLen); |
| 843 - SHA1_HashBuf(hashes->sha, hashBuf, bufLen); |
| 844 + if (hashAlg == SEC_OID_UNKNOWN) { |
| 845 + MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen); |
| 846 + SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen); |
| 847 + hashes->len = MD5_LENGTH + SHA1_LENGTH; |
| 848 + } else if (hashAlg == SEC_OID_SHA1) { |
| 849 + SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen); |
| 850 + hashes->len = SHA1_LENGTH; |
| 851 + } else if (hashAlg == SEC_OID_SHA256) { |
| 852 + SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen); |
| 853 + hashes->len = SHA256_LENGTH; |
| 854 + } else if (hashAlg == SEC_OID_SHA384) { |
| 855 + SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen); |
| 856 + hashes->len = SHA384_LENGTH; |
| 857 + } else { |
| 858 + PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 859 + return SECFailure; |
| 860 + } |
| 861 } else |
| 862 #endif |
| 863 { |
| 864 - rv = PK11_HashBuf(SEC_OID_MD5, hashes->md5, hashBuf, bufLen); |
| 865 - if (rv != SECSuccess) { |
| 866 - ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 867 - rv = SECFailure; |
| 868 - goto done; |
| 869 - } |
| 870 + if (hashAlg == SEC_OID_UNKNOWN) { |
| 871 + rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen); |
| 872 + if (rv != SECSuccess) { |
| 873 + ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 874 + rv = SECFailure; |
| 875 + goto done; |
| 876 + } |
| 877 |
| 878 - rv = PK11_HashBuf(SEC_OID_SHA1, hashes->sha, hashBuf, bufLen); |
| 879 - if (rv != SECSuccess) { |
| 880 - ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 881 - rv = SECFailure; |
| 882 + rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen); |
| 883 + if (rv != SECSuccess) { |
| 884 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 885 + rv = SECFailure; |
| 886 + } |
| 887 + hashes->len = MD5_LENGTH + SHA1_LENGTH; |
| 888 + } else { |
| 889 + hashes->len = HASH_ResultLenByOidTag(hashAlg); |
| 890 + if (hashes->len > sizeof(hashes->u.raw)) { |
| 891 + ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 892 + rv = SECFailure; |
| 893 + goto done; |
| 894 + } |
| 895 + rv = PK11_HashBuf(hashAlg, hashes->u.raw, hashBuf, bufLen); |
| 896 + if (rv != SECSuccess) { |
| 897 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 898 + rv = SECFailure; |
| 899 + } |
| 900 } |
| 901 } |
| 902 + hashes->hashAlg = hashAlg; |
| 903 + |
| 904 done: |
| 905 return rv; |
| 906 } |
| 907 @@ -997,7 +1078,8 @@ |
| 908 ** ssl3_HandleServerKeyExchange. |
| 909 */ |
| 910 static SECStatus |
| 911 -ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent, |
| 912 +ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg, |
| 913 + SECItem modulus, SECItem publicExponent, |
| 914 SSL3Random *client_rand, SSL3Random *server_rand, |
| 915 SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 916 { |
| 917 @@ -1033,11 +1115,19 @@ |
| 918 pBuf += publicExponent.len; |
| 919 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); |
| 920 |
| 921 - rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11); |
| 922 + rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, |
| 923 + bypassPKCS11); |
| 924 |
| 925 PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen)); |
| 926 - PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", hashes->md5, MD5_LENGTH)); |
| 927 - PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", hashes->sha, SHA1_LENGTH))
; |
| 928 + if (hashAlg == SEC_OID_UNKNOWN) { |
| 929 + PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", |
| 930 + hashes->u.s.md5, MD5_LENGTH)); |
| 931 + PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", |
| 932 + hashes->u.s.sha, SHA1_LENGTH)); |
| 933 + } else { |
| 934 + PRINT_BUF(95, (NULL, "RSAkey hash: result", |
| 935 + hashes->u.raw, hashes->len)); |
| 936 + } |
| 937 |
| 938 if (hashBuf != buf && hashBuf != NULL) |
| 939 PORT_Free(hashBuf); |
| 940 @@ -1047,9 +1137,10 @@ |
| 941 /* Caller must set hiLevel error code. */ |
| 942 /* Called from ssl3_HandleServerKeyExchange. */ |
| 943 static SECStatus |
| 944 -ssl3_ComputeDHKeyHash(SECItem dh_p, SECItem dh_g, SECItem dh_Ys, |
| 945 - SSL3Random *client_rand, SSL3Random *server_rand, |
| 946 - SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 947 +ssl3_ComputeDHKeyHash(SECOidTag hashAlg, |
| 948 + SECItem dh_p, SECItem dh_g, SECItem dh_Ys, |
| 949 + SSL3Random *client_rand, SSL3Random *server_rand, |
| 950 + SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 951 { |
| 952 PRUint8 * hashBuf; |
| 953 PRUint8 * pBuf; |
| 954 @@ -1088,11 +1179,19 @@ |
| 955 pBuf += dh_Ys.len; |
| 956 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); |
| 957 |
| 958 - rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11); |
| 959 + rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, |
| 960 + bypassPKCS11); |
| 961 |
| 962 PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen)); |
| 963 - PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", hashes->md5, MD5_LENGTH)); |
| 964 - PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH)); |
| 965 + if (hashAlg == SEC_OID_UNKNOWN) { |
| 966 + PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", |
| 967 + hashes->u.s.md5, MD5_LENGTH)); |
| 968 + PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", |
| 969 + hashes->u.s.sha, SHA1_LENGTH)); |
| 970 + } else { |
| 971 + PRINT_BUF(95, (NULL, "DHkey hash: result", |
| 972 + hashes->u.raw, hashes->len)); |
| 973 + } |
| 974 |
| 975 if (hashBuf != buf && hashBuf != NULL) |
| 976 PORT_Free(hashBuf); |
| 977 @@ -3190,6 +3289,8 @@ |
| 978 unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random; |
| 979 PRBool isTLS = (PRBool)(kea_def->tls_keygen || |
| 980 (pwSpec->version > SSL_LIBRARY_VERSION_3_0)); |
| 981 + PRBool isTLS12= |
| 982 + (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
| 983 /* |
| 984 * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH |
| 985 * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size |
| 986 @@ -3208,7 +3309,12 @@ |
| 987 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 988 PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); |
| 989 PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); |
| 990 - if (isTLS) { |
| 991 + if (isTLS12) { |
| 992 + if(isDH) master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
| 993 + else master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256; |
| 994 + key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256; |
| 995 + keyFlags = CKF_SIGN | CKF_VERIFY; |
| 996 + } else if (isTLS) { |
| 997 if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 998 else master_derive = CKM_TLS_MASTER_KEY_DERIVE; |
| 999 key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; |
| 1000 @@ -3366,6 +3472,8 @@ |
| 1001 unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random; |
| 1002 PRBool isTLS = (PRBool)(kea_def->tls_keygen || |
| 1003 (pwSpec->version > SSL_LIBRARY_VERSION_3_0)); |
| 1004 + PRBool isTLS12= |
| 1005 + (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
| 1006 /* following variables used in PKCS11 path */ |
| 1007 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; |
| 1008 PK11SlotInfo * slot = NULL; |
| 1009 @@ -3423,7 +3531,9 @@ |
| 1010 params.data = (unsigned char *)&key_material_params; |
| 1011 params.len = sizeof(key_material_params); |
| 1012 |
| 1013 - if (isTLS) { |
| 1014 + if (isTLS12) { |
| 1015 + key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256; |
| 1016 + } else if (isTLS) { |
| 1017 key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; |
| 1018 } else { |
| 1019 key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; |
| 1020 @@ -3480,19 +3590,63 @@ |
| 1021 return SECFailure; |
| 1022 } |
| 1023 |
| 1024 +/* ssl3_InitTLS12HandshakeHash creates a handshake hash context for TLS 1.2, |
| 1025 + * if needed, and hashes in any buffered messages in ss->ssl3.hs.messages. */ |
| 1026 +static SECStatus |
| 1027 +ssl3_InitTLS12HandshakeHash(sslSocket *ss) |
| 1028 +{ |
| 1029 + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2 && |
| 1030 + ss->ssl3.hs.tls12_handshake_hash == NULL) { |
| 1031 + /* If we ever support ciphersuites where the PRF hash isn't SHA-256 |
| 1032 + * then this will need to be updated. */ |
| 1033 + ss->ssl3.hs.tls12_handshake_hash = |
| 1034 + PK11_CreateDigestContext(SEC_OID_SHA256); |
| 1035 + if (!ss->ssl3.hs.tls12_handshake_hash || |
| 1036 + PK11_DigestBegin(ss->ssl3.hs.tls12_handshake_hash) != SECSuccess) { |
| 1037 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1038 + return SECFailure; |
| 1039 + } |
| 1040 + } |
| 1041 + |
| 1042 + if (ss->ssl3.hs.tls12_handshake_hash && ss->ssl3.hs.messages.len > 0) { |
| 1043 + if (PK11_DigestOp(ss->ssl3.hs.tls12_handshake_hash, |
| 1044 + ss->ssl3.hs.messages.buf, |
| 1045 + ss->ssl3.hs.messages.len) != SECSuccess) { |
| 1046 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1047 + return SECFailure; |
| 1048 + } |
| 1049 + } |
| 1050 + |
| 1051 + if (ss->ssl3.hs.messages.buf && !ss->opt.bypassPKCS11) { |
| 1052 + PORT_Free(ss->ssl3.hs.messages.buf); |
| 1053 + ss->ssl3.hs.messages.buf = NULL; |
| 1054 + ss->ssl3.hs.messages.len = 0; |
| 1055 + ss->ssl3.hs.messages.space = 0; |
| 1056 + } |
| 1057 + |
| 1058 + return SECSuccess; |
| 1059 +} |
| 1060 + |
| 1061 static SECStatus |
| 1062 ssl3_RestartHandshakeHashes(sslSocket *ss) |
| 1063 { |
| 1064 SECStatus rv = SECSuccess; |
| 1065 |
| 1066 + ss->ssl3.hs.messages.len = 0; |
| 1067 #ifndef NO_PKCS11_BYPASS |
| 1068 if (ss->opt.bypassPKCS11) { |
| 1069 - ss->ssl3.hs.messages.len = 0; |
| 1070 MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx); |
| 1071 SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx); |
| 1072 } else |
| 1073 #endif |
| 1074 { |
| 1075 + if (ss->ssl3.hs.tls12_handshake_hash) { |
| 1076 + rv = PK11_DigestBegin(ss->ssl3.hs.tls12_handshake_hash); |
| 1077 + if (rv != SECSuccess) { |
| 1078 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1079 + return rv; |
| 1080 + } |
| 1081 + } |
| 1082 rv = PK11_DigestBegin(ss->ssl3.hs.md5); |
| 1083 if (rv != SECSuccess) { |
| 1084 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 1085 @@ -3519,25 +3673,21 @@ |
| 1086 * that the master secret will wind up in ... |
| 1087 */ |
| 1088 SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd)); |
| 1089 -#ifndef NO_PKCS11_BYPASS |
| 1090 - if (ss->opt.bypassPKCS11) { |
| 1091 - PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space); |
| 1092 - ss->ssl3.hs.messages.buf = NULL; |
| 1093 - ss->ssl3.hs.messages.space = 0; |
| 1094 - } else |
| 1095 -#endif |
| 1096 - { |
| 1097 - ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5); |
| 1098 - ss->ssl3.hs.sha = sha = PK11_CreateDigestContext(SEC_OID_SHA1); |
| 1099 - if (md5 == NULL) { |
| 1100 - ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 1101 - goto loser; |
| 1102 - } |
| 1103 - if (sha == NULL) { |
| 1104 - ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 1105 - goto loser; |
| 1106 - } |
| 1107 + PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space); |
| 1108 + ss->ssl3.hs.messages.buf = NULL; |
| 1109 + ss->ssl3.hs.messages.space = 0; |
| 1110 + |
| 1111 + ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5); |
| 1112 + ss->ssl3.hs.sha = sha = PK11_CreateDigestContext(SEC_OID_SHA1); |
| 1113 + ss->ssl3.hs.tls12_handshake_hash = NULL; |
| 1114 + if (md5 == NULL) { |
| 1115 + ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 1116 + goto loser; |
| 1117 } |
| 1118 + if (sha == NULL) { |
| 1119 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 1120 + goto loser; |
| 1121 + } |
| 1122 if (SECSuccess == ssl3_RestartHandshakeHashes(ss)) { |
| 1123 return SECSuccess; |
| 1124 } |
| 1125 @@ -3574,6 +3724,17 @@ |
| 1126 |
| 1127 PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l)); |
| 1128 |
| 1129 + if ((ss->version == 0 || ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) && |
| 1130 + !ss->opt.bypassPKCS11 && |
| 1131 + ss->ssl3.hs.tls12_handshake_hash == NULL) { |
| 1132 + /* For TLS 1.2 connections we need to buffer the handshake messages |
| 1133 + * until we have established which PRF hash function to use. */ |
| 1134 + rv = sslBuffer_Append(&ss->ssl3.hs.messages, b, l); |
| 1135 + if (rv != SECSuccess) { |
| 1136 + return rv; |
| 1137 + } |
| 1138 + } |
| 1139 + |
| 1140 #ifndef NO_PKCS11_BYPASS |
| 1141 if (ss->opt.bypassPKCS11) { |
| 1142 MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l); |
| 1143 @@ -3584,16 +3745,24 @@ |
| 1144 return rv; |
| 1145 } |
| 1146 #endif |
| 1147 - rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); |
| 1148 - if (rv != SECSuccess) { |
| 1149 - ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 1150 - return rv; |
| 1151 + if (ss->ssl3.hs.tls12_handshake_hash) { |
| 1152 + rv = PK11_DigestOp(ss->ssl3.hs.tls12_handshake_hash, b, l); |
| 1153 + if (rv != SECSuccess) { |
| 1154 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1155 + return rv; |
| 1156 + } |
| 1157 + } else { |
| 1158 + rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); |
| 1159 + if (rv != SECSuccess) { |
| 1160 + ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 1161 + return rv; |
| 1162 + } |
| 1163 + rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); |
| 1164 + if (rv != SECSuccess) { |
| 1165 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 1166 + return rv; |
| 1167 + } |
| 1168 } |
| 1169 - rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); |
| 1170 - if (rv != SECSuccess) { |
| 1171 - ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 1172 - return rv; |
| 1173 - } |
| 1174 return rv; |
| 1175 } |
| 1176 |
| 1177 @@ -3744,6 +3913,25 @@ |
| 1178 return rv; /* error code set by AppendHandshake, if applicable. */ |
| 1179 } |
| 1180 |
| 1181 +/* ssl3_AppendSignatureAndHashAlgorithm appends the serialisation of |
| 1182 + * |sigAndHash| to the current handshake message. */ |
| 1183 +SECStatus |
| 1184 +ssl3_AppendSignatureAndHashAlgorithm( |
| 1185 + sslSocket *ss, const SSL3SignatureAndHashAlgorithm* sigAndHash) |
| 1186 +{ |
| 1187 + unsigned char serialized[2]; |
| 1188 + |
| 1189 + serialized[0] = ssl3_OIDToTLSHashAlgorithm(sigAndHash->hashAlg); |
| 1190 + if (serialized[0] == 0) { |
| 1191 + PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 1192 + return SECFailure; |
| 1193 + } |
| 1194 + |
| 1195 + serialized[1] = sigAndHash->sigAlg; |
| 1196 + |
| 1197 + return ssl3_AppendHandshake(ss, serialized, sizeof(serialized)); |
| 1198 +} |
| 1199 + |
| 1200 /************************************************************************** |
| 1201 * Consume Handshake functions. |
| 1202 * |
| 1203 @@ -3850,6 +4038,147 @@ |
| 1204 return SECSuccess; |
| 1205 } |
| 1206 |
| 1207 +/* tlsHashOIDMap contains the mapping between TLS hash identifiers and the |
| 1208 + * SECOidTag used internally by NSS. */ |
| 1209 +static const struct { |
| 1210 + int tlsHash; |
| 1211 + SECOidTag oid; |
| 1212 +} tlsHashOIDMap[] = { |
| 1213 + { tls_hash_md5, SEC_OID_MD5 }, |
| 1214 + { tls_hash_sha1, SEC_OID_SHA1 }, |
| 1215 + { tls_hash_sha224, SEC_OID_SHA224 }, |
| 1216 + { tls_hash_sha256, SEC_OID_SHA256 }, |
| 1217 + { tls_hash_sha384, SEC_OID_SHA384 }, |
| 1218 + { tls_hash_sha512, SEC_OID_SHA512 } |
| 1219 +}; |
| 1220 + |
| 1221 +/* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value. |
| 1222 + * If the hash is not recognised, SEC_OID_UNKNOWN is returned. |
| 1223 + * |
| 1224 + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 1225 +SECOidTag |
| 1226 +ssl3_TLSHashAlgorithmToOID(int hashFunc) |
| 1227 +{ |
| 1228 + unsigned int i; |
| 1229 + |
| 1230 + for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) { |
| 1231 + if (hashFunc == tlsHashOIDMap[i].tlsHash) { |
| 1232 + return tlsHashOIDMap[i].oid; |
| 1233 + } |
| 1234 + } |
| 1235 + return SEC_OID_UNKNOWN; |
| 1236 +} |
| 1237 + |
| 1238 +/* ssl3_OIDToTLSHashAlgorithm converts an OID to a TLS hash algorithm |
| 1239 + * identifier. If the hash is not recognised, zero is returned. |
| 1240 + * |
| 1241 + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 1242 +static int |
| 1243 +ssl3_OIDToTLSHashAlgorithm(SECOidTag oid) |
| 1244 +{ |
| 1245 + unsigned int i; |
| 1246 + |
| 1247 + for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) { |
| 1248 + if (oid == tlsHashOIDMap[i].oid) { |
| 1249 + return tlsHashOIDMap[i].tlsHash; |
| 1250 + } |
| 1251 + } |
| 1252 + return 0; |
| 1253 +} |
| 1254 + |
| 1255 +/* ssl3_TLSSignatureAlgorithmForKeyType returns the TLS 1.2 signature algorithm |
| 1256 + * identifier for a given KeyType. */ |
| 1257 +static SECStatus |
| 1258 +ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType, |
| 1259 + TLSSignatureAlgorithm *out) |
| 1260 +{ |
| 1261 + switch (keyType) { |
| 1262 + case rsaKey: |
| 1263 + *out = tls_sig_rsa; |
| 1264 + return SECSuccess; |
| 1265 + case dsaKey: |
| 1266 + *out = tls_sig_dsa; |
| 1267 + return SECSuccess; |
| 1268 + case ecKey: |
| 1269 + *out = tls_sig_ecdsa; |
| 1270 + return SECSuccess; |
| 1271 + default: |
| 1272 + PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 1273 + return SECFailure; |
| 1274 + } |
| 1275 +} |
| 1276 + |
| 1277 +/* ssl3_TLSSignatureAlgorithmForCertificate returns the TLS 1.2 signature |
| 1278 + * algorithm identifier for the given certificate. */ |
| 1279 +static SECStatus |
| 1280 +ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert, |
| 1281 + TLSSignatureAlgorithm *out) |
| 1282 +{ |
| 1283 + SECKEYPublicKey *key; |
| 1284 + KeyType keyType; |
| 1285 + |
| 1286 + key = CERT_ExtractPublicKey(cert); |
| 1287 + if (key == NULL) { |
| 1288 + ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
| 1289 + return SECFailure; |
| 1290 + } |
| 1291 + |
| 1292 + keyType = key->keyType; |
| 1293 + SECKEY_DestroyPublicKey(key); |
| 1294 + return ssl3_TLSSignatureAlgorithmForKeyType(keyType, out); |
| 1295 +} |
| 1296 + |
| 1297 +/* ssl3_CheckSignatureAndHashAlgorithmConsistency checks that the signature |
| 1298 + * algorithm identifier in |sigAndHash| is consistent with the public key in |
| 1299 + * |cert|. If so, SECSuccess is returned. Otherwise, PORT_SetError is called |
| 1300 + * and SECFailure is returned. */ |
| 1301 +SECStatus |
| 1302 +ssl3_CheckSignatureAndHashAlgorithmConsistency( |
| 1303 + const SSL3SignatureAndHashAlgorithm *sigAndHash, CERTCertificate* cert) |
| 1304 +{ |
| 1305 + SECStatus rv; |
| 1306 + TLSSignatureAlgorithm sigAlg; |
| 1307 + |
| 1308 + rv = ssl3_TLSSignatureAlgorithmForCertificate(cert, &sigAlg); |
| 1309 + if (rv != SECSuccess) { |
| 1310 + return rv; |
| 1311 + } |
| 1312 + if (sigAlg != sigAndHash->sigAlg) { |
| 1313 + PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); |
| 1314 + return SECFailure; |
| 1315 + } |
| 1316 + return SECSuccess; |
| 1317 +} |
| 1318 + |
| 1319 +/* ssl3_ConsumeSignatureAndHashAlgorithm reads a SignatureAndHashAlgorithm |
| 1320 + * structure from |b| and puts the resulting value into |out|. |b| and |length| |
| 1321 + * are updated accordingly. |
| 1322 + * |
| 1323 + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 1324 +SECStatus |
| 1325 +ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss, |
| 1326 + SSL3Opaque **b, |
| 1327 + PRUint32 *length, |
| 1328 + SSL3SignatureAndHashAlgorithm *out) |
| 1329 +{ |
| 1330 + unsigned char bytes[2]; |
| 1331 + SECStatus rv; |
| 1332 + |
| 1333 + rv = ssl3_ConsumeHandshake(ss, bytes, sizeof(bytes), b, length); |
| 1334 + if (rv != SECSuccess) { |
| 1335 + return rv; |
| 1336 + } |
| 1337 + |
| 1338 + out->hashAlg = ssl3_TLSHashAlgorithmToOID(bytes[0]); |
| 1339 + if (out->hashAlg == SEC_OID_UNKNOWN) { |
| 1340 + PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 1341 + return SECFailure; |
| 1342 + } |
| 1343 + |
| 1344 + out->sigAlg = bytes[1]; |
| 1345 + return SECSuccess; |
| 1346 +} |
| 1347 + |
| 1348 /************************************************************************** |
| 1349 * end of Consume Handshake functions. |
| 1350 **************************************************************************/ |
| 1351 @@ -3876,6 +4205,7 @@ |
| 1352 SSL3Opaque sha_inner[MAX_MAC_LENGTH]; |
| 1353 |
| 1354 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 1355 + hashes->hashAlg = SEC_OID_UNKNOWN; |
| 1356 |
| 1357 #ifndef NO_PKCS11_BYPASS |
| 1358 if (ss->opt.bypassPKCS11) { |
| 1359 @@ -3939,9 +4269,9 @@ |
| 1360 MD5_Update(md5cx, mac_pad_2, mac_defs[mac_md5].pad_size); |
| 1361 MD5_Update(md5cx, md5_inner, MD5_LENGTH); |
| 1362 } |
| 1363 - MD5_End(md5cx, hashes->md5, &outLength, MD5_LENGTH); |
| 1364 + MD5_End(md5cx, hashes->u.s.md5, &outLength, MD5_LENGTH); |
| 1365 |
| 1366 - PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH)); |
| 1367 + PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH)); |
| 1368 |
| 1369 if (!isTLS) { |
| 1370 PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, |
| 1371 @@ -3953,16 +4283,58 @@ |
| 1372 SHA1_Update(shacx, mac_pad_2, mac_defs[mac_sha].pad_size); |
| 1373 SHA1_Update(shacx, sha_inner, SHA1_LENGTH); |
| 1374 } |
| 1375 - SHA1_End(shacx, hashes->sha, &outLength, SHA1_LENGTH); |
| 1376 + SHA1_End(shacx, hashes->u.s.sha, &outLength, SHA1_LENGTH); |
| 1377 |
| 1378 - PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH)); |
| 1379 + PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH))
; |
| 1380 |
| 1381 + hashes->len = MD5_LENGTH + SHA1_LENGTH; |
| 1382 rv = SECSuccess; |
| 1383 #undef md5cx |
| 1384 #undef shacx |
| 1385 } else |
| 1386 #endif |
| 1387 - { |
| 1388 + if (ss->ssl3.hs.tls12_handshake_hash) { |
| 1389 + PK11Context *h; |
| 1390 + unsigned int stateLen; |
| 1391 + unsigned char stackBuf[1024]; |
| 1392 + unsigned char *stateBuf = NULL; |
| 1393 + |
| 1394 + if (!spec->master_secret) { |
| 1395 + PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); |
| 1396 + return SECFailure; |
| 1397 + } |
| 1398 + |
| 1399 + h = ss->ssl3.hs.tls12_handshake_hash; |
| 1400 + stateBuf = PK11_SaveContextAlloc(h, stackBuf, |
| 1401 + sizeof(stackBuf), &stateLen); |
| 1402 + if (stateBuf == NULL) { |
| 1403 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1404 + goto tls12_loser; |
| 1405 + } |
| 1406 + rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len, |
| 1407 + sizeof(hashes->u.raw)); |
| 1408 + if (rv != SECSuccess) { |
| 1409 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1410 + rv = SECFailure; |
| 1411 + goto tls12_loser; |
| 1412 + } |
| 1413 + /* If we ever support ciphersuites where the PRF hash isn't SHA-256 |
| 1414 + * then this will need to be updated. */ |
| 1415 + hashes->hashAlg = SEC_OID_SHA256; |
| 1416 + rv = SECSuccess; |
| 1417 + |
| 1418 +tls12_loser: |
| 1419 + if (stateBuf) { |
| 1420 + if (PK11_RestoreContext(ss->ssl3.hs.tls12_handshake_hash, stateBuf, |
| 1421 + stateLen) != SECSuccess) { |
| 1422 + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 1423 + rv = SECFailure; |
| 1424 + } |
| 1425 + if (stateBuf != stackBuf) { |
| 1426 + PORT_ZFree(stateBuf, stateLen); |
| 1427 + } |
| 1428 + } |
| 1429 + } else { |
| 1430 /* compute hases with PKCS11 */ |
| 1431 PK11Context * md5; |
| 1432 PK11Context * sha = NULL; |
| 1433 @@ -4051,7 +4423,7 @@ |
| 1434 rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size); |
| 1435 rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH); |
| 1436 } |
| 1437 - rv |= PK11_DigestFinal(md5, hashes->md5, &outLength, MD5_LENGTH); |
| 1438 + rv |= PK11_DigestFinal(md5, hashes->u.s.md5, &outLength, MD5_LENGTH); |
| 1439 PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH); |
| 1440 if (rv != SECSuccess) { |
| 1441 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 1442 @@ -4059,7 +4431,7 @@ |
| 1443 goto loser; |
| 1444 } |
| 1445 |
| 1446 - PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH)); |
| 1447 + PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH)); |
| 1448 |
| 1449 if (!isTLS) { |
| 1450 PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, |
| 1451 @@ -4071,7 +4443,7 @@ |
| 1452 rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size); |
| 1453 rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH); |
| 1454 } |
| 1455 - rv |= PK11_DigestFinal(sha, hashes->sha, &outLength, SHA1_LENGTH); |
| 1456 + rv |= PK11_DigestFinal(sha, hashes->u.s.sha, &outLength, SHA1_LENGTH); |
| 1457 PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH); |
| 1458 if (rv != SECSuccess) { |
| 1459 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 1460 @@ -4079,8 +4451,9 @@ |
| 1461 goto loser; |
| 1462 } |
| 1463 |
| 1464 - PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH)); |
| 1465 + PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH))
; |
| 1466 |
| 1467 + hashes->len = MD5_LENGTH + SHA1_LENGTH; |
| 1468 rv = SECSuccess; |
| 1469 |
| 1470 loser: |
| 1471 @@ -5343,8 +5716,12 @@ |
| 1472 { |
| 1473 SECStatus rv = SECFailure; |
| 1474 PRBool isTLS; |
| 1475 + PRBool isTLS12; |
| 1476 SECItem buf = {siBuffer, NULL, 0}; |
| 1477 SSL3Hashes hashes; |
| 1478 + KeyType keyType; |
| 1479 + unsigned int len; |
| 1480 + SSL3SignatureAndHashAlgorithm sigAndHash; |
| 1481 |
| 1482 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 1483 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 1484 @@ -5393,10 +5772,30 @@ |
| 1485 goto done; /* err code was set by ssl3_SignHashes */ |
| 1486 } |
| 1487 |
| 1488 - rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, buf.len + 2); |
| 1489 + len = buf.len + 2 + (isTLS12 ? 2 : 0); |
| 1490 + |
| 1491 + rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); |
| 1492 if (rv != SECSuccess) { |
| 1493 goto done; /* error code set by AppendHandshake */ |
| 1494 } |
| 1495 + if (isTLS12) { |
| 1496 + rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, |
| 1497 + &sigAndHash.sigAlg); |
| 1498 + if (rv != SECSuccess) { |
| 1499 + goto done; |
| 1500 + } |
| 1501 + /* We always sign using the handshake hash function. It's possible that |
| 1502 + * a server could support SHA-256 as the handshake hash but not as a |
| 1503 + * signature hash. In that case we wouldn't be able to do client |
| 1504 + * certificates with it. The alternative is to buffer all handshake |
| 1505 + * messages. */ |
| 1506 + sigAndHash.hashAlg = hashes.hashAlg; |
| 1507 + |
| 1508 + rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
| 1509 + if (rv != SECSuccess) { |
| 1510 + goto done; /* err set by AppendHandshake. */ |
| 1511 + } |
| 1512 + } |
| 1513 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2); |
| 1514 if (rv != SECSuccess) { |
| 1515 goto done; /* error code set by AppendHandshake */ |
| 1516 @@ -5504,6 +5903,13 @@ |
| 1517 } |
| 1518 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); |
| 1519 |
| 1520 + rv = ssl3_InitTLS12HandshakeHash(ss); |
| 1521 + if (rv != SECSuccess) { |
| 1522 + desc = internal_error; |
| 1523 + errCode = PORT_GetError(); |
| 1524 + goto alert_loser; |
| 1525 + } |
| 1526 + |
| 1527 rv = ssl3_ConsumeHandshake( |
| 1528 ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length); |
| 1529 if (rv != SECSuccess) { |
| 1530 @@ -5834,13 +6240,16 @@ |
| 1531 { |
| 1532 PRArenaPool * arena = NULL; |
| 1533 SECKEYPublicKey *peerKey = NULL; |
| 1534 - PRBool isTLS; |
| 1535 + PRBool isTLS, isTLS12; |
| 1536 SECStatus rv; |
| 1537 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH; |
| 1538 SSL3AlertDescription desc = illegal_parameter; |
| 1539 SSL3Hashes hashes; |
| 1540 SECItem signature = {siBuffer, NULL, 0}; |
| 1541 + SSL3SignatureAndHashAlgorithm sigAndHash; |
| 1542 |
| 1543 + sigAndHash.hashAlg = SEC_OID_UNKNOWN; |
| 1544 + |
| 1545 SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake", |
| 1546 SSL_GETPID(), ss->fd)); |
| 1547 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 1548 @@ -5859,6 +6268,7 @@ |
| 1549 } |
| 1550 |
| 1551 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 1552 + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2)
; |
| 1553 |
| 1554 switch (ss->ssl3.hs.kea_def->exchKeyType) { |
| 1555 |
| 1556 @@ -5874,6 +6284,18 @@ |
| 1557 if (rv != SECSuccess) { |
| 1558 goto loser; /* malformed. */ |
| 1559 } |
| 1560 + if (isTLS12) { |
| 1561 + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
| 1562 + &sigAndHash); |
| 1563 + if (rv != SECSuccess) { |
| 1564 + goto loser; /* malformed or unsupported. */ |
| 1565 + } |
| 1566 + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
| 1567 + &sigAndHash, ss->sec.peerCert); |
| 1568 + if (rv != SECSuccess) { |
| 1569 + goto loser; |
| 1570 + } |
| 1571 + } |
| 1572 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
| 1573 if (rv != SECSuccess) { |
| 1574 goto loser; /* malformed. */ |
| 1575 @@ -5891,7 +6313,7 @@ |
| 1576 /* |
| 1577 * check to make sure the hash is signed by right guy |
| 1578 */ |
| 1579 - rv = ssl3_ComputeExportRSAKeyHash(modulus, exponent, |
| 1580 + rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent, |
| 1581 &ss->ssl3.hs.client_random, |
| 1582 &ss->ssl3.hs.server_random, |
| 1583 &hashes, ss->opt.bypassPKCS11); |
| 1584 @@ -5964,6 +6386,18 @@ |
| 1585 } |
| 1586 if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys)) |
| 1587 goto alert_loser; |
| 1588 + if (isTLS12) { |
| 1589 + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
| 1590 + &sigAndHash); |
| 1591 + if (rv != SECSuccess) { |
| 1592 + goto loser; /* malformed or unsupported. */ |
| 1593 + } |
| 1594 + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
| 1595 + &sigAndHash, ss->sec.peerCert); |
| 1596 + if (rv != SECSuccess) { |
| 1597 + goto loser; |
| 1598 + } |
| 1599 + } |
| 1600 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
| 1601 if (rv != SECSuccess) { |
| 1602 goto loser; /* malformed. */ |
| 1603 @@ -5985,7 +6419,7 @@ |
| 1604 /* |
| 1605 * check to make sure the hash is signed by right guy |
| 1606 */ |
| 1607 - rv = ssl3_ComputeDHKeyHash(dh_p, dh_g, dh_Ys, |
| 1608 + rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys, |
| 1609 &ss->ssl3.hs.client_random, |
| 1610 &ss->ssl3.hs.server_random, |
| 1611 &hashes, ss->opt.bypassPKCS11); |
| 1612 @@ -6862,6 +7296,13 @@ |
| 1613 goto alert_loser; |
| 1614 } |
| 1615 |
| 1616 + rv = ssl3_InitTLS12HandshakeHash(ss); |
| 1617 + if (rv != SECSuccess) { |
| 1618 + desc = internal_error; |
| 1619 + errCode = PORT_GetError(); |
| 1620 + goto alert_loser; |
| 1621 + } |
| 1622 + |
| 1623 /* grab the client random data. */ |
| 1624 rv = ssl3_ConsumeHandshake( |
| 1625 ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length); |
| 1626 @@ -7604,6 +8045,13 @@ |
| 1627 goto alert_loser; |
| 1628 } |
| 1629 |
| 1630 + rv = ssl3_InitTLS12HandshakeHash(ss); |
| 1631 + if (rv != SECSuccess) { |
| 1632 + desc = internal_error; |
| 1633 + errCode = PORT_GetError(); |
| 1634 + goto alert_loser; |
| 1635 + } |
| 1636 + |
| 1637 /* if we get a non-zero SID, just ignore it. */ |
| 1638 if (length != |
| 1639 SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length + rand_length) { |
| 1640 @@ -7851,7 +8299,86 @@ |
| 1641 return SECSuccess; |
| 1642 } |
| 1643 |
| 1644 +/* ssl3_PickSignatureHashAlgorithm selects a hash algorithm to use when signing |
| 1645 + * elements of the handshake. (The negotiated cipher suite determines the |
| 1646 + * signature algorithm.) Prior to TLS 1.2, the MD5/SHA1 combination is always |
| 1647 + * used. With TLS 1.2, a client may advertise its support for signature and |
| 1648 + * hash combinations. */ |
| 1649 +static SECStatus |
| 1650 +ssl3_PickSignatureHashAlgorithm(sslSocket *ss, |
| 1651 + SSL3SignatureAndHashAlgorithm* out) |
| 1652 +{ |
| 1653 + TLSSignatureAlgorithm sigAlg; |
| 1654 + unsigned int i, j; |
| 1655 + /* hashPreference expresses our preferences for hash algorithms, most |
| 1656 + * preferable first. */ |
| 1657 + static const PRUint8 hashPreference[] = { |
| 1658 + tls_hash_sha256, |
| 1659 + tls_hash_sha384, |
| 1660 + tls_hash_sha512, |
| 1661 + tls_hash_sha1, |
| 1662 + }; |
| 1663 |
| 1664 + switch (ss->ssl3.hs.kea_def->kea) { |
| 1665 + case kea_rsa: |
| 1666 + case kea_rsa_export: |
| 1667 + case kea_rsa_export_1024: |
| 1668 + case kea_dh_rsa: |
| 1669 + case kea_dh_rsa_export: |
| 1670 + case kea_dhe_rsa: |
| 1671 + case kea_dhe_rsa_export: |
| 1672 + case kea_rsa_fips: |
| 1673 + case kea_ecdh_rsa: |
| 1674 + case kea_ecdhe_rsa: |
| 1675 + sigAlg = tls_sig_rsa; |
| 1676 + break; |
| 1677 + case kea_dh_dss: |
| 1678 + case kea_dh_dss_export: |
| 1679 + case kea_dhe_dss: |
| 1680 + case kea_dhe_dss_export: |
| 1681 + sigAlg = tls_sig_dsa; |
| 1682 + break; |
| 1683 + case kea_ecdh_ecdsa: |
| 1684 + case kea_ecdhe_ecdsa: |
| 1685 + sigAlg = tls_sig_ecdsa; |
| 1686 + break; |
| 1687 + default: |
| 1688 + PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); |
| 1689 + return SECFailure; |
| 1690 + } |
| 1691 + out->sigAlg = sigAlg; |
| 1692 + |
| 1693 + if (ss->version <= SSL_LIBRARY_VERSION_TLS_1_1) { |
| 1694 + /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and |
| 1695 + * prior. */ |
| 1696 + out->hashAlg = SEC_OID_UNKNOWN; |
| 1697 + return SECSuccess; |
| 1698 + } |
| 1699 + |
| 1700 + if (ss->ssl3.hs.numClientSigAndHash == 0) { |
| 1701 + /* If the client didn't provide any signature_algorithms extension then |
| 1702 + * we can assume that they support SHA-1: |
| 1703 + * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
| 1704 + out->hashAlg = SEC_OID_SHA1; |
| 1705 + return SECSuccess; |
| 1706 + } |
| 1707 + |
| 1708 + for (i = 0; i < PR_ARRAY_SIZE(hashPreference); i++) { |
| 1709 + for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) { |
| 1710 + const SSL3SignatureAndHashAlgorithm* sh = |
| 1711 + &ss->ssl3.hs.clientSigAndHash[j]; |
| 1712 + if (sh->sigAlg == sigAlg && sh->hashAlg == hashPreference[i]) { |
| 1713 + out->hashAlg = sh->hashAlg; |
| 1714 + return SECSuccess; |
| 1715 + } |
| 1716 + } |
| 1717 + } |
| 1718 + |
| 1719 + PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 1720 + return SECFailure; |
| 1721 +} |
| 1722 + |
| 1723 + |
| 1724 static SECStatus |
| 1725 ssl3_SendServerKeyExchange(sslSocket *ss) |
| 1726 { |
| 1727 @@ -7862,6 +8389,7 @@ |
| 1728 SECItem signed_hash = {siBuffer, NULL, 0}; |
| 1729 SSL3Hashes hashes; |
| 1730 SECKEYPublicKey * sdPub; /* public key for step-down */ |
| 1731 + SSL3SignatureAndHashAlgorithm sigAndHash; |
| 1732 |
| 1733 SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake", |
| 1734 SSL_GETPID(), ss->fd)); |
| 1735 @@ -7869,6 +8397,10 @@ |
| 1736 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 1737 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 1738 |
| 1739 + if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) { |
| 1740 + return SECFailure; |
| 1741 + } |
| 1742 + |
| 1743 switch (kea_def->exchKeyType) { |
| 1744 case kt_rsa: |
| 1745 /* Perform SSL Step-Down here. */ |
| 1746 @@ -7878,7 +8410,8 @@ |
| 1747 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 1748 return SECFailure; |
| 1749 } |
| 1750 - rv = ssl3_ComputeExportRSAKeyHash(sdPub->u.rsa.modulus, |
| 1751 + rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, |
| 1752 + sdPub->u.rsa.modulus, |
| 1753 sdPub->u.rsa.publicExponent, |
| 1754 &ss->ssl3.hs.client_random, |
| 1755 &ss->ssl3.hs.server_random, |
| 1756 @@ -7921,6 +8454,13 @@ |
| 1757 goto loser; /* err set by AppendHandshake. */ |
| 1758 } |
| 1759 |
| 1760 + if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { |
| 1761 + rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
| 1762 + if (rv != SECSuccess) { |
| 1763 + goto loser; /* err set by AppendHandshake. */ |
| 1764 + } |
| 1765 + } |
| 1766 + |
| 1767 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, |
| 1768 signed_hash.len, 2); |
| 1769 if (rv != SECSuccess) { |
| 1770 @@ -7931,7 +8471,7 @@ |
| 1771 |
| 1772 #ifdef NSS_ENABLE_ECC |
| 1773 case kt_ecdh: { |
| 1774 - rv = ssl3_SendECDHServerKeyExchange(ss); |
| 1775 + rv = ssl3_SendECDHServerKeyExchange(ss, &sigAndHash); |
| 1776 return rv; |
| 1777 } |
| 1778 #endif /* NSS_ENABLE_ECC */ |
| 1779 @@ -8045,26 +8585,51 @@ |
| 1780 SECStatus rv; |
| 1781 int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY; |
| 1782 SSL3AlertDescription desc = handshake_failure; |
| 1783 - PRBool isTLS; |
| 1784 + PRBool isTLS, isTLS12; |
| 1785 + SSL3SignatureAndHashAlgorithm sigAndHash; |
| 1786 |
| 1787 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake", |
| 1788 SSL_GETPID(), ss->fd)); |
| 1789 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 1790 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 1791 |
| 1792 + isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 1793 + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2)
; |
| 1794 + |
| 1795 if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) { |
| 1796 desc = unexpected_message; |
| 1797 errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY; |
| 1798 goto alert_loser; |
| 1799 } |
| 1800 |
| 1801 + if (isTLS12) { |
| 1802 + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
| 1803 + &sigAndHash); |
| 1804 + if (rv != SECSuccess) { |
| 1805 + goto loser; /* malformed or unsupported. */ |
| 1806 + } |
| 1807 + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
| 1808 + &sigAndHash, ss->sec.peerCert); |
| 1809 + if (rv != SECSuccess) { |
| 1810 + errCode = PORT_GetError(); |
| 1811 + desc = decrypt_error; |
| 1812 + goto alert_loser; |
| 1813 + } |
| 1814 + |
| 1815 + /* We only support CertificateVerify messages that use the handshake |
| 1816 + * hash. */ |
| 1817 + if (sigAndHash.hashAlg != hashes->hashAlg) { |
| 1818 + errCode = SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM; |
| 1819 + desc = decrypt_error; |
| 1820 + goto alert_loser; |
| 1821 + } |
| 1822 + } |
| 1823 + |
| 1824 rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length); |
| 1825 if (rv != SECSuccess) { |
| 1826 goto loser; /* malformed. */ |
| 1827 } |
| 1828 |
| 1829 - isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 1830 - |
| 1831 /* XXX verify that the key & kea match */ |
| 1832 rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash, |
| 1833 isTLS, ss->pkcs11PinArg); |
| 1834 @@ -9163,7 +9728,7 @@ |
| 1835 static SECStatus |
| 1836 ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, |
| 1837 PRBool isServer, |
| 1838 - const SSL3Finished * hashes, |
| 1839 + const SSL3Hashes * hashes, |
| 1840 TLSFinished * tlsFinished) |
| 1841 { |
| 1842 const char * label; |
| 1843 @@ -9173,8 +9738,8 @@ |
| 1844 label = isServer ? "server finished" : "client finished"; |
| 1845 len = 15; |
| 1846 |
| 1847 - rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->md5, |
| 1848 - sizeof *hashes, tlsFinished->verify_data, |
| 1849 + rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw, |
| 1850 + hashes->len, tlsFinished->verify_data, |
| 1851 sizeof tlsFinished->verify_data); |
| 1852 |
| 1853 return rv; |
| 1854 @@ -9192,12 +9757,16 @@ |
| 1855 SECStatus rv = SECSuccess; |
| 1856 |
| 1857 if (spec->master_secret && !spec->bypassCiphers) { |
| 1858 - SECItem param = {siBuffer, NULL, 0}; |
| 1859 - PK11Context *prf_context = |
| 1860 - PK11_CreateContextBySymKey(CKM_TLS_PRF_GENERAL, CKA_SIGN, |
| 1861 - spec->master_secret, ¶m); |
| 1862 + SECItem param = {siBuffer, NULL, 0}; |
| 1863 + CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL; |
| 1864 + PK11Context *prf_context; |
| 1865 unsigned int retLen; |
| 1866 |
| 1867 + if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { |
| 1868 + mech = CKM_NSS_TLS_PRF_GENERAL_SHA256; |
| 1869 + } |
| 1870 + prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN, |
| 1871 + spec->master_secret, ¶m); |
| 1872 if (!prf_context) |
| 1873 return SECFailure; |
| 1874 |
| 1875 @@ -9496,7 +10066,7 @@ |
| 1876 PRBool isServer = ss->sec.isServer; |
| 1877 SECStatus rv; |
| 1878 SSL3Sender sender = isServer ? sender_server : sender_client; |
| 1879 - SSL3Finished hashes; |
| 1880 + SSL3Hashes hashes; |
| 1881 TLSFinished tlsFinished; |
| 1882 |
| 1883 SSL_TRC(3, ("%d: SSL3[%d]: send finished handshake", SSL_GETPID(), ss->fd))
; |
| 1884 @@ -9530,14 +10100,15 @@ |
| 1885 goto fail; /* err set by AppendHandshake. */ |
| 1886 } else { |
| 1887 if (isServer) |
| 1888 - ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes; |
| 1889 + ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes.u.s; |
| 1890 else |
| 1891 - ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes; |
| 1892 - ss->ssl3.hs.finishedBytes = sizeof hashes; |
| 1893 - rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes); |
| 1894 + ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s; |
| 1895 + PORT_Assert(hashes.len == sizeof hashes.u.s); |
| 1896 + ss->ssl3.hs.finishedBytes = sizeof hashes.u.s; |
| 1897 + rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes.u.s); |
| 1898 if (rv != SECSuccess) |
| 1899 goto fail; /* err set by AppendHandshake. */ |
| 1900 - rv = ssl3_AppendHandshake(ss, &hashes, sizeof hashes); |
| 1901 + rv = ssl3_AppendHandshake(ss, &hashes.u.s, sizeof hashes.u.s); |
| 1902 if (rv != SECSuccess) |
| 1903 goto fail; /* err set by AppendHandshake. */ |
| 1904 } |
| 1905 @@ -9686,18 +10257,19 @@ |
| 1906 return SECFailure; |
| 1907 } |
| 1908 } else { |
| 1909 - if (length != sizeof(SSL3Hashes)) { |
| 1910 + if (length != sizeof(SSL3Finished)) { |
| 1911 (void)ssl3_IllegalParameter(ss); |
| 1912 PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED); |
| 1913 return SECFailure; |
| 1914 } |
| 1915 |
| 1916 if (!isServer) |
| 1917 - ss->ssl3.hs.finishedMsgs.sFinished[1] = *hashes; |
| 1918 + ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes->u.s; |
| 1919 else |
| 1920 - ss->ssl3.hs.finishedMsgs.sFinished[0] = *hashes; |
| 1921 - ss->ssl3.hs.finishedBytes = sizeof *hashes; |
| 1922 - if (0 != NSS_SecureMemcmp(hashes, b, length)) { |
| 1923 + ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes->u.s; |
| 1924 + PORT_Assert(hashes->len == sizeof hashes->u.s); |
| 1925 + ss->ssl3.hs.finishedBytes = sizeof hashes->u.s; |
| 1926 + if (0 != NSS_SecureMemcmp(&hashes->u.s, b, length)) { |
| 1927 (void)ssl3_HandshakeFailure(ss); |
| 1928 PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
| 1929 return SECFailure; |
| 1930 @@ -11286,6 +11858,12 @@ |
| 1931 if (ss->ssl3.hs.sha) { |
| 1932 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); |
| 1933 } |
| 1934 + if (ss->ssl3.hs.tls12_handshake_hash) { |
| 1935 + PK11_DestroyContext(ss->ssl3.hs.tls12_handshake_hash,PR_TRUE); |
| 1936 + } |
| 1937 + if (ss->ssl3.hs.clientSigAndHash) { |
| 1938 + PORT_Free(ss->ssl3.hs.clientSigAndHash); |
| 1939 + } |
| 1940 if (ss->ssl3.hs.messages.buf) { |
| 1941 PORT_Free(ss->ssl3.hs.messages.buf); |
| 1942 ss->ssl3.hs.messages.buf = NULL; |
OLD | NEW |