1 Index: net/third_party/nss/ssl/ssl3con.c 2 =================================================================== 3 --- net/third_party/nss/ssl/ssl3con.c (revision 220594) 4 +++ net/third_party/nss/ssl/ssl3con.c (working copy) 5 @@ -3933,6 +3933,20 @@ 6 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); 7 return SECFailure; 8 } 9 + 10 + /* A backup SHA-1 hash for a potential client auth signature. */ 11 + if (!ss->sec.isServer) { 12 + ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1); 13 + if (ss->ssl3.hs.md5 == NULL) { 14 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 15 + return SECFailure; 16 + } 17 + 18 + if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) { 19 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 20 + return SECFailure; 21 + } 22 + } 23 } else { 24 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or 25 * created successfully. */ 26 @@ -4043,6 +4057,13 @@ 27 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); 28 return rv; 29 } 30 + if (ss->ssl3.hs.md5) { 31 + rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); 32 + if (rv != SECSuccess) { 33 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 34 + return rv; 35 + } 36 + } 37 } else { 38 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); 39 if (rv != SECSuccess) { 40 @@ -4791,6 +4812,30 @@ 41 return rv; 42 } 43 44 +static SECStatus 45 +ssl3_ComputeBackupHandshakeHashes(sslSocket * ss, 46 + SSL3Hashes * hashes) /* output goes here. */ 47 +{ 48 + SECStatus rv = SECSuccess; 49 + 50 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); 51 + PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single ); 52 + 53 + rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len, 54 + sizeof(hashes->u.raw)); 55 + if (rv != SECSuccess) { 56 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 57 + rv = SECFailure; 58 + goto loser; 59 + } 60 + hashes->hashAlg = SEC_OID_SHA1; 61 + 62 +loser: 63 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); 64 + ss->ssl3.hs.md5 = NULL; 65 + return rv; 66 +} 67 + 68 /* 69 * SSL 2 based implementations pass in the initial outbound buffer 70 * so that the handshake hash can contain the included information. 71 @@ -6044,7 +6089,17 @@ 72 SSL_GETPID(), ss->fd)); 73 74 ssl_GetSpecReadLock(ss); 75 - rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); 76 + /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash 77 + * function (SHA-256). If the server or the client does not support SHA-256 78 + * as a signature hash, we can either maintain a backup SHA-1 handshake 79 + * hash or buffer all handshake messages. 80 + */ 81 + if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { 82 + rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes); 83 + PORT_Assert(ss->ssl3.hs.md5 == NULL); 84 + } else { 85 + rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); 86 + } 87 ssl_ReleaseSpecReadLock(ss); 88 if (rv != SECSuccess) { 89 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ 90 @@ -6098,11 +6153,6 @@ 91 if (rv != SECSuccess) { 92 goto done; 93 } 94 - /* We always sign using the handshake hash function. It's possible that 95 - * a server could support SHA-256 as the handshake hash but not as a 96 - * signature hash. In that case we wouldn't be able to do client 97 - * certificates with it. The alternative is to buffer all handshake 98 - * messages. */ 99 sigAndHash.hashAlg = hashes.hashAlg; 100 101 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); 102 @@ -6802,6 +6852,70 @@ 103 } 104 105 106 +/* 107 + * Returns true if the client authentication key is an RSA or DSA key that 108 + * may be able to sign only SHA-1 hashes. 109 + */ 110 +static PRBool 111 +ssl3_ClientKeyPrefersSHA1(sslSocket *ss) 112 +{ 113 + SECKEYPublicKey *pubk; 114 + PRBool prefer_sha1 = PR_FALSE; 115 + 116 +#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32) 117 + /* If the key is in CAPI, assume conservatively that the CAPI service 118 + * provider may be unable to sign SHA-256 hashes. 119 + */ 120 + if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) { 121 + /* CAPI only supports RSA and DSA signatures, so we don't need to 122 + * check the key type. */ 123 + return PR_TRUE; 124 + } 125 +#endif /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */ 126 + 127 + /* If the key is a 1024-bit RSA or DSA key, assume conservatively that 128 + * it may be unable to sign SHA-256 hashes. This is the case for older 129 + * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and 130 + * older, DSA key size is at most 1024 bits and the hash function must 131 + * be SHA-1. 132 + */ 133 + pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); 134 + if (pubk == NULL) { 135 + return PR_FALSE; 136 + } 137 + if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) { 138 + prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128; 139 + } 140 + SECKEY_DestroyPublicKey(pubk); 141 + return prefer_sha1; 142 +} 143 + 144 +/* Destroys the backup handshake hash context if we don't need it. */ 145 +static void 146 +ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, 147 + const SECItem *algorithms) 148 +{ 149 + PRBool need_backup_hash = PR_FALSE; 150 + unsigned int i; 151 + 152 + PORT_Assert(ss->ssl3.hs.md5); 153 + if (ssl3_ClientKeyPrefersSHA1(ss)) { 154 + /* Use SHA-1 if the server supports it. */ 155 + for (i = 0; i < algorithms->len; i += 2) { 156 + if (algorithms->data[i] == tls_hash_sha1 && 157 + (algorithms->data[i+1] == tls_sig_rsa || 158 + algorithms->data[i+1] == tls_sig_dsa)) { 159 + need_backup_hash = PR_TRUE; 160 + break; 161 + } 162 + } 163 + } 164 + if (!need_backup_hash) { 165 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); 166 + ss->ssl3.hs.md5 = NULL; 167 + } 168 +} 169 + 170 typedef struct dnameNode { 171 struct dnameNode *next; 172 SECItem name; 173 @@ -6994,6 +7108,9 @@ 174 } 175 goto send_no_certificate; 176 } 177 + if (isTLS12) { 178 + ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms); 179 + } 180 break; /* not an error */ 181 } 182 #endif /* NSS_PLATFORM_CLIENT_AUTH */ 183 @@ -7029,6 +7146,9 @@ 184 } 185 goto send_no_certificate; 186 } 187 + if (isTLS12) { 188 + ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms); 189 + } 190 break; /* not an error */ 191 192 case SECFailure: 193 @@ -7227,6 +7347,13 @@ 194 (ss->ssl3.platformClientKey || 195 ss->ssl3.clientPrivateKey != NULL); 196 197 + if (!sendClientCert && 198 + ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { 199 + /* Don't need the backup handshake hash. */ 200 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); 201 + ss->ssl3.hs.md5 = NULL; 202 + } 203 + 204 /* We must wait for the server's certificate to be authenticated before 205 * sending the client certificate in order to disclosing the client 206 * certificate to an attacker that does not have a valid cert for the 207 Index: net/third_party/nss/ssl/sslimpl.h 208 =================================================================== 209 --- net/third_party/nss/ssl/sslimpl.h (revision 220594) 210 +++ net/third_party/nss/ssl/sslimpl.h (working copy) 211 @@ -838,6 +838,9 @@ 212 * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and 213 * |sha| for SHA-1. 214 * TLS 1.2 and later use only |sha|, for SHA-256. */ 215 + /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup 216 + * handshake hash for generating client auth signatures. Confusingly, the 217 + * backup hash function is SHA-1. */ 218 PK11Context * md5; 219 PK11Context * sha; 220 221