Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| 2 /* | 2 /* |
| 3 * SSL3 Protocol | 3 * SSL3 Protocol |
| 4 * | 4 * |
| 5 * This Source Code Form is subject to the terms of the Mozilla Public | 5 * This Source Code Form is subject to the terms of the Mozilla Public |
| 6 * License, v. 2.0. If a copy of the MPL was not distributed with this | 6 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 8 | 8 |
| 9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ | 9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ |
| 10 | 10 |
| (...skipping 3915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3926 if (ss->ssl3.hs.sha == NULL) { | 3926 if (ss->ssl3.hs.sha == NULL) { |
| 3927 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); | 3927 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 3928 return SECFailure; | 3928 return SECFailure; |
| 3929 } | 3929 } |
| 3930 ss->ssl3.hs.hashType = handshake_hash_single; | 3930 ss->ssl3.hs.hashType = handshake_hash_single; |
| 3931 | 3931 |
| 3932 if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) { | 3932 if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) { |
| 3933 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); | 3933 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 3934 return SECFailure; | 3934 return SECFailure; |
| 3935 } | 3935 } |
| 3936 | |
| 3937 #ifdef _WIN32 | |
| 3938 /* A backup SHA-1 hash for a potential client auth signature. */ | |
| 3939 if (!ss->sec.isServer) { | |
| 3940 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1); | |
| 3941 if (ss->ssl3.hs.md5 == NULL) { | |
| 3942 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); | |
| 3943 return SECFailure; | |
| 3944 } | |
| 3945 | |
| 3946 if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) { | |
| 3947 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); | |
| 3948 return SECFailure; | |
| 3949 } | |
| 3950 } | |
| 3951 #endif | |
| 3936 } else { | 3952 } else { |
| 3937 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or | 3953 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or |
| 3938 * created successfully. */ | 3954 * created successfully. */ |
| 3939 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5); | 3955 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5); |
| 3940 if (ss->ssl3.hs.md5 == NULL) { | 3956 if (ss->ssl3.hs.md5 == NULL) { |
| 3941 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); | 3957 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 3942 return SECFailure; | 3958 return SECFailure; |
| 3943 } | 3959 } |
| 3944 ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1); | 3960 ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1); |
| 3945 if (ss->ssl3.hs.sha == NULL) { | 3961 if (ss->ssl3.hs.sha == NULL) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4036 } | 4052 } |
| 4037 return rv; | 4053 return rv; |
| 4038 } | 4054 } |
| 4039 #endif | 4055 #endif |
| 4040 if (ss->ssl3.hs.hashType == handshake_hash_single) { | 4056 if (ss->ssl3.hs.hashType == handshake_hash_single) { |
| 4041 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); | 4057 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); |
| 4042 if (rv != SECSuccess) { | 4058 if (rv != SECSuccess) { |
| 4043 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); | 4059 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
| 4044 return rv; | 4060 return rv; |
| 4045 } | 4061 } |
| 4062 if (ss->ssl3.hs.md5) { | |
| 4063 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); | |
| 4064 if (rv != SECSuccess) { | |
| 4065 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); | |
| 4066 return rv; | |
| 4067 } | |
| 4068 } | |
| 4046 } else { | 4069 } else { |
| 4047 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); | 4070 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); |
| 4048 if (rv != SECSuccess) { | 4071 if (rv != SECSuccess) { |
| 4049 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); | 4072 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
| 4050 return rv; | 4073 return rv; |
| 4051 } | 4074 } |
| 4052 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); | 4075 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); |
| 4053 if (rv != SECSuccess) { | 4076 if (rv != SECSuccess) { |
| 4054 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); | 4077 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
| 4055 return rv; | 4078 return rv; |
| (...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4784 rv = SECFailure; | 4807 rv = SECFailure; |
| 4785 } | 4808 } |
| 4786 if (shaStateBuf != shaStackBuf) { | 4809 if (shaStateBuf != shaStackBuf) { |
| 4787 PORT_ZFree(shaStateBuf, shaStateLen); | 4810 PORT_ZFree(shaStateBuf, shaStateLen); |
| 4788 } | 4811 } |
| 4789 } | 4812 } |
| 4790 } | 4813 } |
| 4791 return rv; | 4814 return rv; |
| 4792 } | 4815 } |
| 4793 | 4816 |
| 4817 static SECStatus | |
| 4818 ssl3_ComputeBackupHandshakeHashes(sslSocket * ss, | |
| 4819 SSL3Hashes * hashes) /* output goes here. */ | |
| 4820 { | |
| 4821 SECStatus rv = SECSuccess; | |
| 4822 | |
| 4823 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | |
| 4824 PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single ); | |
| 4825 | |
| 4826 rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len, | |
| 4827 sizeof(hashes->u.raw)); | |
| 4828 if (rv != SECSuccess) { | |
| 4829 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); | |
| 4830 rv = SECFailure; | |
| 4831 goto loser; | |
| 4832 } | |
| 4833 hashes->hashAlg = SEC_OID_SHA1; | |
| 4834 | |
| 4835 loser: | |
| 4836 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); | |
| 4837 ss->ssl3.hs.md5 = NULL; | |
| 4838 return rv; | |
| 4839 } | |
| 4840 | |
| 4794 /* | 4841 /* |
| 4795 * SSL 2 based implementations pass in the initial outbound buffer | 4842 * SSL 2 based implementations pass in the initial outbound buffer |
| 4796 * so that the handshake hash can contain the included information. | 4843 * so that the handshake hash can contain the included information. |
| 4797 * | 4844 * |
| 4798 * Called from ssl2_BeginClientHandshake() in sslcon.c | 4845 * Called from ssl2_BeginClientHandshake() in sslcon.c |
| 4799 */ | 4846 */ |
| 4800 SECStatus | 4847 SECStatus |
| 4801 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length) | 4848 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length) |
| 4802 { | 4849 { |
| 4803 SECStatus rv; | 4850 SECStatus rv; |
| (...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6037 unsigned int len; | 6084 unsigned int len; |
| 6038 SSL3SignatureAndHashAlgorithm sigAndHash; | 6085 SSL3SignatureAndHashAlgorithm sigAndHash; |
| 6039 | 6086 |
| 6040 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 6087 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 6041 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 6088 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 6042 | 6089 |
| 6043 SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake", | 6090 SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake", |
| 6044 SSL_GETPID(), ss->fd)); | 6091 SSL_GETPID(), ss->fd)); |
| 6045 | 6092 |
| 6046 ssl_GetSpecReadLock(ss); | 6093 ssl_GetSpecReadLock(ss); |
| 6047 rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); | 6094 /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash |
| 6095 * function (SHA-256). If the server or the client does not support SHA-256 | |
| 6096 * as a signature hash, we can either maintain a backup SHA-1 handshake | |
| 6097 * hash or buffer all handshake messages. | |
| 6098 */ | |
| 6099 if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { | |
| 6100 » rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes); | |
|
agl
2013/08/28 22:16:03
(doesn't matter): here you are using tabs rather t
| |
| 6101 » PORT_Assert(ss->ssl3.hs.md5 == NULL); | |
| 6102 } else { | |
| 6103 » rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); | |
| 6104 } | |
| 6048 ssl_ReleaseSpecReadLock(ss); | 6105 ssl_ReleaseSpecReadLock(ss); |
| 6049 if (rv != SECSuccess) { | 6106 if (rv != SECSuccess) { |
| 6050 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ | 6107 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ |
| 6051 } | 6108 } |
| 6052 | 6109 |
| 6053 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 6110 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 6054 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 6111 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
| 6055 if (ss->ssl3.platformClientKey) { | 6112 if (ss->ssl3.platformClientKey) { |
| 6056 #ifdef NSS_PLATFORM_CLIENT_AUTH | 6113 #ifdef NSS_PLATFORM_CLIENT_AUTH |
| 6057 keyType = CERT_GetCertKeyType( | 6114 keyType = CERT_GetCertKeyType( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6091 rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); | 6148 rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); |
| 6092 if (rv != SECSuccess) { | 6149 if (rv != SECSuccess) { |
| 6093 goto done; /* error code set by AppendHandshake */ | 6150 goto done; /* error code set by AppendHandshake */ |
| 6094 } | 6151 } |
| 6095 if (isTLS12) { | 6152 if (isTLS12) { |
| 6096 rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, | 6153 rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, |
| 6097 &sigAndHash.sigAlg); | 6154 &sigAndHash.sigAlg); |
| 6098 if (rv != SECSuccess) { | 6155 if (rv != SECSuccess) { |
| 6099 goto done; | 6156 goto done; |
| 6100 } | 6157 } |
| 6101 /* We always sign using the handshake hash function. It's possible that | |
| 6102 * a server could support SHA-256 as the handshake hash but not as a | |
| 6103 * signature hash. In that case we wouldn't be able to do client | |
| 6104 * certificates with it. The alternative is to buffer all handshake | |
| 6105 * messages. */ | |
| 6106 sigAndHash.hashAlg = hashes.hashAlg; | 6158 sigAndHash.hashAlg = hashes.hashAlg; |
| 6107 | 6159 |
| 6108 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); | 6160 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
| 6109 if (rv != SECSuccess) { | 6161 if (rv != SECSuccess) { |
| 6110 goto done; /* err set by AppendHandshake. */ | 6162 goto done; /* err set by AppendHandshake. */ |
| 6111 } | 6163 } |
| 6112 } | 6164 } |
| 6113 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2); | 6165 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2); |
| 6114 if (rv != SECSuccess) { | 6166 if (rv != SECSuccess) { |
| 6115 goto done; /* error code set by AppendHandshake */ | 6167 goto done; /* error code set by AppendHandshake */ |
| (...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6987 if (ss->ssl3.clientCertificate != NULL) { | 7039 if (ss->ssl3.clientCertificate != NULL) { |
| 6988 CERT_DestroyCertificate(ss->ssl3.clientCertificate); | 7040 CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
| 6989 ss->ssl3.clientCertificate = NULL; | 7041 ss->ssl3.clientCertificate = NULL; |
| 6990 } | 7042 } |
| 6991 if (ss->ssl3.platformClientKey) { | 7043 if (ss->ssl3.platformClientKey) { |
| 6992 ssl_FreePlatformKey(ss->ssl3.platformClientKey); | 7044 ssl_FreePlatformKey(ss->ssl3.platformClientKey); |
| 6993 ss->ssl3.platformClientKey = (PlatformKey)NULL; | 7045 ss->ssl3.platformClientKey = (PlatformKey)NULL; |
| 6994 } | 7046 } |
| 6995 goto send_no_certificate; | 7047 goto send_no_certificate; |
| 6996 } | 7048 } |
| 7049 | |
| 7050 if (isTLS12 && ss->ssl3.hs.md5) { | |
| 7051 PRBool need_backup_hash = PR_FALSE; | |
| 7052 #ifdef _WIN32 | |
| 7053 /* If the key is in CAPI, check if the CAPI service provider | |
| 7054 * supports SHA-256. Use SHA-1 if it doesn't. */ | |
| 7055 if (ss->ssl3.platformClientKey->dwKeySpec != | |
| 7056 CERT_NCRYPT_KEY_SPEC) { | |
| 7057 HCRYPTPROV prov = ss->ssl3.platformClientKey->hCryptProv; | |
| 7058 PROV_ENUMALGS alg_info; | |
| 7059 DWORD size = sizeof(alg_info); | |
| 7060 DWORD flags = CRYPT_FIRST; | |
| 7061 need_backup_hash = PR_TRUE; | |
| 7062 while (CryptGetProvParam(prov, PP_ENUMALGS, | |
|
wtc
2013/08/28 22:05:45
It may be cheaper to check SHA-256 support by tryi
| |
| 7063 (BYTE *)&alg_info, &size, flags)) { | |
| 7064 if (alg_info.aiAlgid == CALG_SHA_256) { | |
| 7065 need_backup_hash = PR_FALSE; | |
| 7066 break; | |
| 7067 } | |
| 7068 size = sizeof(alg_info); | |
| 7069 flags = CRYPT_NEXT; | |
| 7070 } | |
| 7071 } | |
| 7072 #endif /* _WIN32 */ | |
| 7073 if (!need_backup_hash) { | |
| 7074 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); | |
| 7075 ss->ssl3.hs.md5 = NULL; | |
| 7076 } | |
| 7077 } | |
| 6997 break; /* not an error */ | 7078 break; /* not an error */ |
| 6998 } | 7079 } |
| 6999 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 7080 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
| 7000 /* check what the callback function returned */ | 7081 /* check what the callback function returned */ |
| 7001 if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { | 7082 if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { |
| 7002 /* we are missing either the key or cert */ | 7083 /* we are missing either the key or cert */ |
| 7003 if (ss->ssl3.clientCertificate) { | 7084 if (ss->ssl3.clientCertificate) { |
| 7004 /* got a cert, but no key - free it */ | 7085 /* got a cert, but no key - free it */ |
| 7005 CERT_DestroyCertificate(ss->ssl3.clientCertificate); | 7086 CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
| 7006 ss->ssl3.clientCertificate = NULL; | 7087 ss->ssl3.clientCertificate = NULL; |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7220 PRBool sendClientCert; | 7301 PRBool sendClientCert; |
| 7221 | 7302 |
| 7222 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 7303 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 7223 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 7304 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 7224 | 7305 |
| 7225 sendClientCert = !ss->ssl3.sendEmptyCert && | 7306 sendClientCert = !ss->ssl3.sendEmptyCert && |
| 7226 ss->ssl3.clientCertChain != NULL && | 7307 ss->ssl3.clientCertChain != NULL && |
| 7227 (ss->ssl3.platformClientKey || | 7308 (ss->ssl3.platformClientKey || |
| 7228 ss->ssl3.clientPrivateKey != NULL); | 7309 ss->ssl3.clientPrivateKey != NULL); |
| 7229 | 7310 |
| 7311 if (!sendClientCert && | |
| 7312 ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { | |
| 7313 /* Don't need the backup handshake hash. */ | |
| 7314 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); | |
| 7315 ss->ssl3.hs.md5 = NULL; | |
| 7316 } | |
| 7317 | |
| 7230 /* We must wait for the server's certificate to be authenticated before | 7318 /* We must wait for the server's certificate to be authenticated before |
| 7231 * sending the client certificate in order to disclosing the client | 7319 * sending the client certificate in order to disclosing the client |
| 7232 * certificate to an attacker that does not have a valid cert for the | 7320 * certificate to an attacker that does not have a valid cert for the |
| 7233 * domain we are connecting to. | 7321 * domain we are connecting to. |
| 7234 * | 7322 * |
| 7235 * XXX: We should do the same for the NPN extension, but for that we | 7323 * XXX: We should do the same for the NPN extension, but for that we |
| 7236 * need an option to give the application the ability to leak the NPN | 7324 * need an option to give the application the ability to leak the NPN |
| 7237 * information to get better performance. | 7325 * information to get better performance. |
| 7238 * | 7326 * |
| 7239 * During the initial handshake on a connection, we never send/receive | 7327 * During the initial handshake on a connection, we never send/receive |
| (...skipping 5024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12264 PORT_Free(ss->ssl3.hs.recvdFragments.buf); | 12352 PORT_Free(ss->ssl3.hs.recvdFragments.buf); |
| 12265 } | 12353 } |
| 12266 } | 12354 } |
| 12267 | 12355 |
| 12268 ss->ssl3.initialized = PR_FALSE; | 12356 ss->ssl3.initialized = PR_FALSE; |
| 12269 | 12357 |
| 12270 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | 12358 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 12271 } | 12359 } |
| 12272 | 12360 |
| 12273 /* End of ssl3con.c */ | 12361 /* End of ssl3con.c */ |
| OLD | NEW |