OLD | NEW |
(Empty) | |
| 1 Index: net/third_party/nss/ssl/ssl3con.c |
| 2 =================================================================== |
| 3 --- net/third_party/nss/ssl/ssl3con.c (revision 219342) |
| 4 +++ net/third_party/nss/ssl/ssl3con.c (working copy) |
| 5 @@ -3933,6 +3933,22 @@ |
| 6 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 7 return SECFailure; |
| 8 } |
| 9 + |
| 10 +#ifdef _WIN32 |
| 11 + /* A backup SHA-1 hash for a potential client auth signature. */ |
| 12 + if (!ss->sec.isServer) { |
| 13 + ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1); |
| 14 + if (ss->ssl3.hs.md5 == NULL) { |
| 15 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 16 + return SECFailure; |
| 17 + } |
| 18 + |
| 19 + if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) { |
| 20 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 21 + return SECFailure; |
| 22 + } |
| 23 + } |
| 24 +#endif |
| 25 } else { |
| 26 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or |
| 27 * created successfully. */ |
| 28 @@ -4043,6 +4059,13 @@ |
| 29 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 30 return rv; |
| 31 } |
| 32 + if (ss->ssl3.hs.md5) { |
| 33 + rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); |
| 34 + if (rv != SECSuccess) { |
| 35 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 36 + return rv; |
| 37 + } |
| 38 + } |
| 39 } else { |
| 40 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); |
| 41 if (rv != SECSuccess) { |
| 42 @@ -4791,6 +4814,30 @@ |
| 43 return rv; |
| 44 } |
| 45 |
| 46 +static SECStatus |
| 47 +ssl3_ComputeBackupHandshakeHashes(sslSocket * ss, |
| 48 + SSL3Hashes * hashes) /* output goes here. */ |
| 49 +{ |
| 50 + SECStatus rv = SECSuccess; |
| 51 + |
| 52 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 53 + PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single ); |
| 54 + |
| 55 + rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len, |
| 56 + sizeof(hashes->u.raw)); |
| 57 + if (rv != SECSuccess) { |
| 58 + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 59 + rv = SECFailure; |
| 60 + goto loser; |
| 61 + } |
| 62 + hashes->hashAlg = SEC_OID_SHA1; |
| 63 + |
| 64 +loser: |
| 65 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); |
| 66 + ss->ssl3.hs.md5 = NULL; |
| 67 + return rv; |
| 68 +} |
| 69 + |
| 70 /* |
| 71 * SSL 2 based implementations pass in the initial outbound buffer |
| 72 * so that the handshake hash can contain the included information. |
| 73 @@ -6044,7 +6091,17 @@ |
| 74 SSL_GETPID(), ss->fd)); |
| 75 |
| 76 ssl_GetSpecReadLock(ss); |
| 77 - rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); |
| 78 + /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash |
| 79 + * function (SHA-256). If the server or the client does not support SHA-256 |
| 80 + * as a signature hash, we can either maintain a backup SHA-1 handshake |
| 81 + * hash or buffer all handshake messages. |
| 82 + */ |
| 83 + if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { |
| 84 + rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes); |
| 85 + PORT_Assert(ss->ssl3.hs.md5 == NULL); |
| 86 + } else { |
| 87 + rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); |
| 88 + } |
| 89 ssl_ReleaseSpecReadLock(ss); |
| 90 if (rv != SECSuccess) { |
| 91 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ |
| 92 @@ -6098,11 +6155,6 @@ |
| 93 if (rv != SECSuccess) { |
| 94 goto done; |
| 95 } |
| 96 - /* We always sign using the handshake hash function. It's possible that |
| 97 - * a server could support SHA-256 as the handshake hash but not as a |
| 98 - * signature hash. In that case we wouldn't be able to do client |
| 99 - * certificates with it. The alternative is to buffer all handshake |
| 100 - * messages. */ |
| 101 sigAndHash.hashAlg = hashes.hashAlg; |
| 102 |
| 103 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
| 104 @@ -6994,6 +7046,35 @@ |
| 105 } |
| 106 goto send_no_certificate; |
| 107 } |
| 108 + |
| 109 + if (isTLS12 && ss->ssl3.hs.md5) { |
| 110 + PRBool need_backup_hash = PR_FALSE; |
| 111 +#ifdef _WIN32 |
| 112 + /* If the key is in CAPI, check if the CAPI service provider |
| 113 + * supports SHA-256. Use SHA-1 if it doesn't. */ |
| 114 + if (ss->ssl3.platformClientKey->dwKeySpec != |
| 115 + CERT_NCRYPT_KEY_SPEC) { |
| 116 + HCRYPTPROV prov = ss->ssl3.platformClientKey->hCryptProv; |
| 117 + PROV_ENUMALGS alg_info; |
| 118 + DWORD size = sizeof(alg_info); |
| 119 + DWORD flags = CRYPT_FIRST; |
| 120 + need_backup_hash = PR_TRUE; |
| 121 + while (CryptGetProvParam(prov, PP_ENUMALGS, |
| 122 + (BYTE *)&alg_info, &size, flags)) { |
| 123 + if (alg_info.aiAlgid == CALG_SHA_256) { |
| 124 + need_backup_hash = PR_FALSE; |
| 125 + break; |
| 126 + } |
| 127 + size = sizeof(alg_info); |
| 128 + flags = CRYPT_NEXT; |
| 129 + } |
| 130 + } |
| 131 +#endif /* _WIN32 */ |
| 132 + if (!need_backup_hash) { |
| 133 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); |
| 134 + ss->ssl3.hs.md5 = NULL; |
| 135 + } |
| 136 + } |
| 137 break; /* not an error */ |
| 138 } |
| 139 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
| 140 @@ -7227,6 +7308,13 @@ |
| 141 (ss->ssl3.platformClientKey || |
| 142 ss->ssl3.clientPrivateKey != NULL); |
| 143 |
| 144 + if (!sendClientCert && |
| 145 + ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { |
| 146 + /* Don't need the backup handshake hash. */ |
| 147 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); |
| 148 + ss->ssl3.hs.md5 = NULL; |
| 149 + } |
| 150 + |
| 151 /* We must wait for the server's certificate to be authenticated before |
| 152 * sending the client certificate in order to disclosing the client |
| 153 * certificate to an attacker that does not have a valid cert for the |
| 154 Index: net/third_party/nss/ssl/sslimpl.h |
| 155 =================================================================== |
| 156 --- net/third_party/nss/ssl/sslimpl.h (revision 219342) |
| 157 +++ net/third_party/nss/ssl/sslimpl.h (working copy) |
| 158 @@ -838,6 +838,9 @@ |
| 159 * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and |
| 160 * |sha| for SHA-1. |
| 161 * TLS 1.2 and later use only |sha|, for SHA-256. */ |
| 162 + /* NOTE: On Windows, TLS 1.2 and later use |md5| as a backup handshake hash |
| 163 + * for generating client auth signatures. Confusingly, the backup hash |
| 164 + * function is SHA-1. */ |
| 165 PK11Context * md5; |
| 166 PK11Context * sha; |
| 167 |
OLD | NEW |