Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: net/third_party/nss/ssl/ssl3con.c

Issue 10424013: Support TLS Channel IDs in NSS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698