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 * ***** BEGIN LICENSE BLOCK ***** | 5 * ***** BEGIN LICENSE BLOCK ***** |
| 6 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 6 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 7 * | 7 * |
| 8 * The contents of this file are subject to the Mozilla Public License Version | 8 * The contents of this file are subject to the Mozilla Public License Version |
| 9 * 1.1 (the "License"); you may not use this file except in compliance with | 9 * 1.1 (the "License"); you may not use this file except in compliance with |
| 10 * the License. You may obtain a copy of the License at | 10 * the License. You may obtain a copy of the License at |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, | 79 static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, |
| 80 PK11SlotInfo * serverKeySlot); | 80 PK11SlotInfo * serverKeySlot); |
| 81 static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); | 81 static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); |
| 82 static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss); | 82 static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss); |
| 83 static SECStatus ssl3_HandshakeFailure( sslSocket *ss); | 83 static SECStatus ssl3_HandshakeFailure( sslSocket *ss); |
| 84 static SECStatus ssl3_InitState( sslSocket *ss); | 84 static SECStatus ssl3_InitState( sslSocket *ss); |
| 85 static SECStatus ssl3_SendCertificate( sslSocket *ss); | 85 static SECStatus ssl3_SendCertificate( sslSocket *ss); |
| 86 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); | 86 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); |
| 87 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); | 87 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); |
| 88 static SECStatus ssl3_SendNextProto( sslSocket *ss); | 88 static SECStatus ssl3_SendNextProto( sslSocket *ss); |
| 89 static SECStatus ssl3_SendEncryptedExtensions(sslSocket *ss); | |
| 89 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); | 90 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); |
| 90 static SECStatus ssl3_SendServerHello( sslSocket *ss); | 91 static SECStatus ssl3_SendServerHello( sslSocket *ss); |
| 91 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); | 92 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); |
| 92 static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss); | 93 static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss); |
| 93 static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss); | 94 static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss); |
| 94 static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, | 95 static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, |
| 95 const unsigned char *b, | 96 const unsigned char *b, |
| 96 unsigned int l); | 97 unsigned int l); |
| 97 static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); | 98 static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); |
| 98 | 99 |
| (...skipping 6132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6231 } | 6232 } |
| 6232 | 6233 |
| 6233 /* XXX: If the server's certificate hasn't been authenticated by this | 6234 /* XXX: If the server's certificate hasn't been authenticated by this |
| 6234 * point, then we may be leaking this NPN message to an attacker. | 6235 * point, then we may be leaking this NPN message to an attacker. |
| 6235 */ | 6236 */ |
| 6236 if (!ss->firstHsDone) { | 6237 if (!ss->firstHsDone) { |
| 6237 rv = ssl3_SendNextProto(ss); | 6238 rv = ssl3_SendNextProto(ss); |
| 6238 if (rv != SECSuccess) { | 6239 if (rv != SECSuccess) { |
| 6239 goto loser; /* err code was set. */ | 6240 goto loser; /* err code was set. */ |
| 6240 } | 6241 } |
| 6242 rv = ssl3_SendEncryptedExtensions(ss); | |
| 6243 if (rv != SECSuccess) { | |
| 6244 goto loser; /* err code was set. */ | |
| 6245 } | |
| 6241 } | 6246 } |
| 6242 | 6247 |
| 6243 rv = ssl3_SendFinished(ss, 0); | 6248 rv = ssl3_SendFinished(ss, 0); |
| 6244 if (rv != SECSuccess) { | 6249 if (rv != SECSuccess) { |
| 6245 goto loser; /* err code was set. */ | 6250 goto loser; /* err code was set. */ |
| 6246 } | 6251 } |
| 6247 | 6252 |
| 6248 ssl_ReleaseXmitBufLock(ss); /*******************************/ | 6253 ssl_ReleaseXmitBufLock(ss); /*******************************/ |
| 6249 | 6254 |
| 6250 if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) | 6255 if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) |
| (...skipping 2563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8814 inData.data = (unsigned char *) val; | 8819 inData.data = (unsigned char *) val; |
| 8815 inData.len = valLen; | 8820 inData.len = valLen; |
| 8816 outData.data = out; | 8821 outData.data = out; |
| 8817 outData.len = outLen; | 8822 outData.len = outLen; |
| 8818 rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS); | 8823 rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS); |
| 8819 PORT_Assert(rv != SECSuccess || outData.len == outLen); | 8824 PORT_Assert(rv != SECSuccess || outData.len == outLen); |
| 8820 } | 8825 } |
| 8821 return rv; | 8826 return rv; |
| 8822 } | 8827 } |
| 8823 | 8828 |
| 8824 /* called from ssl3_HandleServerHelloDone | 8829 /* called from ssl3_HandleServerHelloDone |
|
wtc
2012/05/24 23:10:03
This comment is incomplete -- ssl3_SendNextProto i
agl
2012/05/30 15:28:33
Yes, that's correct. I'll avoid changing it here t
| |
| 8825 */ | 8830 */ |
| 8826 static SECStatus | 8831 static SECStatus |
| 8827 ssl3_SendNextProto(sslSocket *ss) | 8832 ssl3_SendNextProto(sslSocket *ss) |
| 8828 { | 8833 { |
| 8829 SECStatus rv; | 8834 SECStatus rv; |
| 8830 int padding_len; | 8835 int padding_len; |
| 8831 static const unsigned char padding[32] = {0}; | 8836 static const unsigned char padding[32] = {0}; |
| 8832 | 8837 |
| 8833 if (ss->ssl3.nextProto.len == 0) | 8838 if (ss->ssl3.nextProto.len == 0) |
| 8834 return SECSuccess; | 8839 return SECSuccess; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 8848 if (rv != SECSuccess) { | 8853 if (rv != SECSuccess) { |
| 8849 return rv; /* error code set by AppendHandshake */ | 8854 return rv; /* error code set by AppendHandshake */ |
| 8850 } | 8855 } |
| 8851 rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1); | 8856 rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1); |
| 8852 if (rv != SECSuccess) { | 8857 if (rv != SECSuccess) { |
| 8853 return rv; /* error code set by AppendHandshake */ | 8858 return rv; /* error code set by AppendHandshake */ |
| 8854 } | 8859 } |
| 8855 return rv; | 8860 return rv; |
| 8856 } | 8861 } |
| 8857 | 8862 |
| 8858 /* called from ssl3_HandleServerHelloDone | 8863 /* called from ssl3_HandleServerHelloDone |
|
wtc
2012/05/24 23:10:03
This comment should be updated in the same way.
agl
2012/05/30 15:28:33
Done.
| |
| 8864 */ | |
| 8865 static SECStatus | |
| 8866 ssl3_SendEncryptedExtensions(sslSocket *ss) | |
|
wtc
2012/05/24 23:10:03
Ideally this function should be structured so that
| |
| 8867 { | |
| 8868 SECStatus rv = SECFailure; | |
| 8869 SECItem *spki = NULL; | |
| 8870 SSL3Hashes hashes; | |
| 8871 const unsigned char *pub_bytes; | |
| 8872 static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature"; | |
| 8873 unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + sizeof(SSL3Hashes)]; | |
|
wtc
2012/05/24 23:10:03
IMPORTANT: By using sizeof(CHANNEL_ID_MAGIC), the
agl
2012/05/30 15:28:33
Yes, I intended to include the NUL byte. It's not
| |
| 8874 unsigned char digest[SHA256_LENGTH]; | |
| 8875 SECItem digest_item; | |
| 8876 unsigned char signature[64]; | |
| 8877 SECItem signature_item; | |
| 8878 | |
| 8879 if (!ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) | |
| 8880 return SECSuccess; | |
|
wtc
2012/05/24 23:10:03
Move these two lines after the lock assertions:
agl
2012/05/30 15:28:33
Done.
| |
| 8881 | |
| 8882 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | |
| 8883 PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 8884 PORT_Assert(ss->ssl3.channelID); | |
| 8885 | |
| 8886 /* ChannelIDs are always 128 bytes long: 64 bytes of P-256 public key and 64 | |
| 8887 * bytes of ECDSA signature. */ | |
| 8888 static const int CHANNEL_ID_PUBLIC_KEY_LENGTH = 64; | |
| 8889 static const int CHANNEL_ID_LENGTH = 128; | |
|
wtc
2012/05/24 23:10:03
Move these two lines up to the variable declaratio
agl
2012/05/30 15:28:33
Done.
| |
| 8890 | |
| 8891 if (SECKEY_GetPrivateKeyType(ss->ssl3.channelID) != ecKey || | |
| 8892 PK11_SignatureLen(ss->ssl3.channelID) != sizeof(signature)) { | |
| 8893 PORT_SetError(SSL_ERROR_INVALID_CHANNEL_ID_KEY); | |
| 8894 return SECFailure; | |
| 8895 } | |
| 8896 | |
| 8897 rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, PR_TRUE); | |
|
wtc
2012/05/24 23:10:03
Pass 0 as the last argument. It is only used by S
agl
2012/05/30 15:28:33
Done.
| |
| 8898 if (rv != SECSuccess) | |
| 8899 goto loser; | |
| 8900 | |
| 8901 rv = ssl3_AppendHandshakeHeader(ss, encrypted_extensions, | |
| 8902 2 + 2 + CHANNEL_ID_LENGTH); | |
| 8903 if (rv != SECSuccess) | |
| 8904 return rv; /* error code set by AppendHandshakeHeader */ | |
| 8905 rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2); | |
| 8906 if (rv != SECSuccess) | |
| 8907 return rv; /* error code set by AppendHandshake */ | |
| 8908 rv = ssl3_AppendHandshakeNumber(ss, CHANNEL_ID_LENGTH, 2); | |
| 8909 if (rv != SECSuccess) | |
| 8910 return rv; /* error code set by AppendHandshake */ | |
| 8911 | |
| 8912 spki = SECKEY_EncodeDERSubjectPublicKeyInfo(ss->ssl3.channelIDPub); | |
| 8913 | |
| 8914 /* This is the ASN.1 prefix for a P-256 public key. Specifically it's: | |
| 8915 * SEQUENCE | |
| 8916 * SEQUENCE | |
| 8917 * OID id-ecPublicKey | |
| 8918 * OID prime256v1 | |
| 8919 * BIT STRING, length 66, 0 trailing bits: 0x04 | |
| 8920 * | |
| 8921 * The 0x04 in the BIT STRING is the prefix for an uncompressed, X9.62 | |
| 8922 * public key. Following that are the two field elements as 32-byte, | |
| 8923 * big-endian numbers, as required by the Channel ID. */ | |
| 8924 static const unsigned char P256_SPKI_PREFIX[] = { | |
|
wtc
2012/05/24 23:10:03
Move this up to the variable declaration section.
agl
2012/05/30 15:28:33
Done.
| |
| 8925 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, | |
| 8926 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, | |
| 8927 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, | |
| 8928 0x42, 0x00, 0x04 | |
| 8929 }; | |
| 8930 | |
| 8931 if (spki->len != sizeof(P256_SPKI_PREFIX) + CHANNEL_ID_PUBLIC_KEY_LENGTH || | |
| 8932 memcmp(spki->data, P256_SPKI_PREFIX, sizeof(P256_SPKI_PREFIX) != 0)) { | |
| 8933 PORT_SetError(SSL_ERROR_INVALID_CHANNEL_ID_KEY); | |
| 8934 return SECFailure; | |
|
wtc
2012/05/24 23:10:03
Replace
return SECFailure;
by
rv =
agl
2012/05/30 15:28:33
Good catch, thanks!
| |
| 8935 } | |
| 8936 | |
| 8937 pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX); | |
| 8938 | |
| 8939 memcpy(signed_data, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC)); | |
| 8940 memcpy(signed_data + sizeof(CHANNEL_ID_MAGIC), &hashes, sizeof(hashes)); | |
| 8941 | |
| 8942 rv = SHA256_HashBuf(digest, signed_data, sizeof(signed_data)); | |
|
wtc
2012/05/24 23:10:03
Please use the PK11_ function instead:
rv = PK1
agl
2012/05/30 15:28:33
Done.
| |
| 8943 if (rv != SECSuccess) | |
| 8944 goto loser; | |
| 8945 | |
| 8946 digest_item.data = (void*) &digest; | |
|
wtc
2012/05/24 23:10:03
BUG: I believe this should be
digest_item.data
agl
2012/05/30 15:28:33
Yes, that's the case. However it's surprising so I
| |
| 8947 digest_item.len = sizeof(digest); | |
| 8948 | |
| 8949 signature_item.data = (void*) &signature; | |
| 8950 signature_item.len = sizeof(signature); | |
| 8951 | |
| 8952 rv = PK11_Sign(ss->ssl3.channelID, &signature_item, &digest_item); | |
| 8953 if (rv != SECSuccess) | |
| 8954 goto loser; | |
| 8955 | |
| 8956 rv = ssl3_AppendHandshake(ss, pub_bytes, CHANNEL_ID_PUBLIC_KEY_LENGTH); | |
| 8957 rv = ssl3_AppendHandshake(ss, signature, sizeof(signature)); | |
| 8958 | |
| 8959 rv = SECSuccess; | |
|
wtc
2012/05/24 23:10:03
BUG: remove this line because it suppresses the fa
agl
2012/05/30 15:28:33
Thanks!
| |
| 8960 | |
| 8961 loser: | |
| 8962 if (spki) | |
| 8963 SECITEM_FreeItem(spki, PR_TRUE); | |
| 8964 | |
| 8965 return rv; | |
| 8966 } | |
| 8967 | |
| 8968 /* called from ssl3_HandleServerHelloDone | |
| 8859 * ssl3_HandleClientHello | 8969 * ssl3_HandleClientHello |
| 8860 * ssl3_HandleFinished | 8970 * ssl3_HandleFinished |
| 8861 */ | 8971 */ |
| 8862 static SECStatus | 8972 static SECStatus |
| 8863 ssl3_SendFinished(sslSocket *ss, PRInt32 flags) | 8973 ssl3_SendFinished(sslSocket *ss, PRInt32 flags) |
| 8864 { | 8974 { |
| 8865 ssl3CipherSpec *cwSpec; | 8975 ssl3CipherSpec *cwSpec; |
| 8866 PRBool isTLS; | 8976 PRBool isTLS; |
| 8867 PRBool isServer = ss->sec.isServer; | 8977 PRBool isServer = ss->sec.isServer; |
| 8868 SECStatus rv; | 8978 SECStatus rv; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9103 */ | 9213 */ |
| 9104 if (ss->writerThread == PR_GetCurrentThread()) { | 9214 if (ss->writerThread == PR_GetCurrentThread()) { |
| 9105 flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; | 9215 flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; |
| 9106 } | 9216 } |
| 9107 | 9217 |
| 9108 if (!isServer && !ss->firstHsDone) { | 9218 if (!isServer && !ss->firstHsDone) { |
| 9109 rv = ssl3_SendNextProto(ss); | 9219 rv = ssl3_SendNextProto(ss); |
| 9110 if (rv != SECSuccess) { | 9220 if (rv != SECSuccess) { |
| 9111 goto xmit_loser; /* err code was set. */ | 9221 goto xmit_loser; /* err code was set. */ |
| 9112 } | 9222 } |
| 9223 rv = ssl3_SendEncryptedExtensions(ss); | |
|
wtc
2012/05/24 23:10:03
This means Channel ID must not be used in renegoti
agl
2012/05/30 15:28:33
It did, but that is no longer correct. I've moved
| |
| 9224 if (rv != SECSuccess) { | |
| 9225 goto xmit_loser; /* err code was set. */ | |
| 9226 } | |
| 9113 } | 9227 } |
| 9114 | 9228 |
| 9115 if (IS_DTLS(ss)) { | 9229 if (IS_DTLS(ss)) { |
| 9116 flags |= ssl_SEND_FLAG_NO_RETRANSMIT; | 9230 flags |= ssl_SEND_FLAG_NO_RETRANSMIT; |
| 9117 } | 9231 } |
| 9118 | 9232 |
| 9119 rv = ssl3_SendFinished(ss, flags); | 9233 rv = ssl3_SendFinished(ss, flags); |
| 9120 if (rv != SECSuccess) { | 9234 if (rv != SECSuccess) { |
| 9121 goto xmit_loser; /* err is set. */ | 9235 goto xmit_loser; /* err is set. */ |
| 9122 } | 9236 } |
| (...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10408 SECITEM_FreeItem(&ss->ssl3.hs.cert_status, PR_FALSE); | 10522 SECITEM_FreeItem(&ss->ssl3.hs.cert_status, PR_FALSE); |
| 10409 } | 10523 } |
| 10410 | 10524 |
| 10411 /* free the SSL3Buffer (msg_body) */ | 10525 /* free the SSL3Buffer (msg_body) */ |
| 10412 PORT_Free(ss->ssl3.hs.msg_body.buf); | 10526 PORT_Free(ss->ssl3.hs.msg_body.buf); |
| 10413 | 10527 |
| 10414 /* free up the CipherSpecs */ | 10528 /* free up the CipherSpecs */ |
| 10415 ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/); | 10529 ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/); |
| 10416 ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/); | 10530 ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/); |
| 10417 | 10531 |
| 10532 if (ss->ssl3.channelID) | |
| 10533 SECKEY_DestroyPrivateKey(ss->ssl3.channelID); | |
| 10534 if (ss->ssl3.channelIDPub) | |
| 10535 SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub); | |
|
wtc
2012/05/24 23:10:03
I suggest adding these right after line 10499 (whe
agl
2012/05/30 15:28:33
Done.
| |
| 10536 | |
| 10418 /* Destroy the DTLS data */ | 10537 /* Destroy the DTLS data */ |
| 10419 if (IS_DTLS(ss)) { | 10538 if (IS_DTLS(ss)) { |
| 10420 if (ss->ssl3.hs.lastMessageFlight) { | 10539 if (ss->ssl3.hs.lastMessageFlight) { |
| 10421 dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight); | 10540 dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight); |
| 10422 PORT_Free(ss->ssl3.hs.lastMessageFlight); | 10541 PORT_Free(ss->ssl3.hs.lastMessageFlight); |
| 10423 } | 10542 } |
| 10424 if (ss->ssl3.hs.recvdFragments.buf) { | 10543 if (ss->ssl3.hs.recvdFragments.buf) { |
| 10425 PORT_Free(ss->ssl3.hs.recvdFragments.buf); | 10544 PORT_Free(ss->ssl3.hs.recvdFragments.buf); |
| 10426 } | 10545 } |
| 10427 } | 10546 } |
| 10428 | 10547 |
| 10429 ss->ssl3.initialized = PR_FALSE; | 10548 ss->ssl3.initialized = PR_FALSE; |
| 10430 | 10549 |
| 10431 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | 10550 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 10432 } | 10551 } |
| 10433 | 10552 |
| 10434 /* End of ssl3con.c */ | 10553 /* End of ssl3con.c */ |
| OLD | NEW |