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 4775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4786 if (unwrappedWrappingKey) { | 4786 if (unwrappedWrappingKey) { |
| 4787 *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey); | 4787 *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey); |
| 4788 } | 4788 } |
| 4789 | 4789 |
| 4790 loser: | 4790 loser: |
| 4791 done: | 4791 done: |
| 4792 PZ_Unlock(symWrapKeysLock); | 4792 PZ_Unlock(symWrapKeysLock); |
| 4793 return unwrappedWrappingKey; | 4793 return unwrappedWrappingKey; |
| 4794 } | 4794 } |
| 4795 | 4795 |
| 4796 /* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2| | |
| 4797 * bytes to |out|. */ | |
| 4798 static hexEncode(char *out, const unsigned char *in, size_t length) { | |
| 4799 static const char hextable[] = "0123456789abcdef"; | |
| 4800 size_t i; | |
| 4801 | |
| 4802 for (i = 0; i < length; i++) { | |
| 4803 *(out++) = hextable[in[i] >> 4]; | |
| 4804 *(out++) = hextable[in[i] & 15]; | |
| 4805 } | |
| 4806 } | |
| 4807 | |
|
wtc
2012/06/06 21:29:18
Nit: delete one blank line here.
Nit: use indenta
agl
2012/06/07 15:31:42
Done.
| |
| 4796 | 4808 |
| 4797 /* Called from ssl3_SendClientKeyExchange(). */ | 4809 /* Called from ssl3_SendClientKeyExchange(). */ |
| 4798 /* Presently, this always uses PKCS11. There is no bypass for this. */ | 4810 /* Presently, this always uses PKCS11. There is no bypass for this. */ |
| 4799 static SECStatus | 4811 static SECStatus |
| 4800 sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) | 4812 sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
| 4801 { | 4813 { |
| 4802 PK11SymKey * pms = NULL; | 4814 PK11SymKey * pms = NULL; |
| 4803 SECStatus rv = SECFailure; | 4815 SECStatus rv = SECFailure; |
| 4804 SECItem enc_pms = {siBuffer, NULL, 0}; | 4816 SECItem enc_pms = {siBuffer, NULL, 0}; |
| 4805 PRBool isTLS; | 4817 PRBool isTLS; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 4825 goto loser; /* err set by PORT_Alloc */ | 4837 goto loser; /* err set by PORT_Alloc */ |
| 4826 } | 4838 } |
| 4827 | 4839 |
| 4828 /* wrap pre-master secret in server's public key. */ | 4840 /* wrap pre-master secret in server's public key. */ |
| 4829 rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms); | 4841 rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms); |
| 4830 if (rv != SECSuccess) { | 4842 if (rv != SECSuccess) { |
| 4831 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 4843 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
| 4832 goto loser; | 4844 goto loser; |
| 4833 } | 4845 } |
| 4834 | 4846 |
| 4835 #if defined(TRACE) | 4847 if (ssl_keylog_iob) { |
| 4836 if (ssl_trace >= 100 || ssl_keylog_iob) { | |
| 4837 SECStatus extractRV = PK11_ExtractKeyValue(pms); | 4848 SECStatus extractRV = PK11_ExtractKeyValue(pms); |
| 4838 if (extractRV == SECSuccess) { | 4849 if (extractRV == SECSuccess) { |
| 4839 SECItem * keyData = PK11_GetKeyData(pms); | 4850 SECItem * keyData = PK11_GetKeyData(pms); |
| 4840 if (keyData && keyData->data && keyData->len) { | 4851 if (keyData && keyData->data && keyData->len) { |
| 4852 #ifdef TRACE | |
| 4841 if (ssl_trace >= 100) { | 4853 if (ssl_trace >= 100) { |
| 4842 ssl_PrintBuf(ss, "Pre-Master Secret", | 4854 ssl_PrintBuf(ss, "Pre-Master Secret", |
| 4843 keyData->data, keyData->len); | 4855 keyData->data, keyData->len); |
| 4844 } | 4856 } |
| 4857 #endif | |
| 4845 if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) { | 4858 if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) { |
| 4846 /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ | 4859 /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ |
| 4847 | 4860 |
| 4848 /* There could be multiple, concurrent writers to the | 4861 /* There could be multiple, concurrent writers to the |
| 4849 * keylog, so we have to do everything in a single call to | 4862 * keylog, so we have to do everything in a single call to |
| 4850 * fwrite. */ | 4863 * fwrite. */ |
| 4851 char buf[4 + 8*2 + 1 + 48*2 + 1]; | 4864 char buf[4 + 8*2 + 1 + 48*2 + 1]; |
| 4852 static const char hextable[16] = "0123456789abcdef"; | |
| 4853 unsigned int i; | |
| 4854 | 4865 |
| 4855 strcpy(buf, "RSA "); | 4866 strcpy(buf, "RSA "); |
| 4856 | 4867 » » hexEncode(buf + 4, enc_pms.data, 8); |
| 4857 » » for (i = 0; i < 8; i++) { | |
| 4858 » » » buf[4 + i*2] = hextable[enc_pms.data[i] >> 4]; | |
| 4859 » » » buf[4 + i*2 + 1] = hextable[enc_pms.data[i] & 15]; | |
| 4860 » » } | |
| 4861 buf[20] = ' '; | 4868 buf[20] = ' '; |
| 4862 | 4869 » » hexEncode(buf + 21, keyData->data, 48); |
| 4863 » » for (i = 0; i < 48; i++) { | |
| 4864 » » » buf[21 + i*2] = hextable[keyData->data[i] >> 4]; | |
| 4865 » » » buf[21 + i*2 + 1] = hextable[keyData->data[i] & 15]; | |
| 4866 » » } | |
| 4867 buf[sizeof(buf) - 1] = '\n'; | 4870 buf[sizeof(buf) - 1] = '\n'; |
| 4868 | 4871 |
| 4869 fwrite(buf, sizeof(buf), 1, ssl_keylog_iob); | 4872 fwrite(buf, sizeof(buf), 1, ssl_keylog_iob); |
| 4870 fflush(ssl_keylog_iob); | 4873 fflush(ssl_keylog_iob); |
| 4871 } | 4874 } |
| 4872 } | 4875 } |
| 4873 } | 4876 } |
| 4874 } | 4877 } |
| 4875 #endif | |
| 4876 | 4878 |
| 4877 rv = ssl3_InitPendingCipherSpec(ss, pms); | 4879 rv = ssl3_InitPendingCipherSpec(ss, pms); |
| 4878 PK11_FreeSymKey(pms); pms = NULL; | 4880 PK11_FreeSymKey(pms); pms = NULL; |
| 4879 | 4881 |
| 4880 if (rv != SECSuccess) { | 4882 if (rv != SECSuccess) { |
| 4881 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 4883 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
| 4882 goto loser; | 4884 goto loser; |
| 4883 } | 4885 } |
| 4884 | 4886 |
| 4885 rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, | 4887 rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, |
| (...skipping 4153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9039 if (ss->ssl3.channelIDPub) | 9041 if (ss->ssl3.channelIDPub) |
| 9040 SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub); | 9042 SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub); |
| 9041 | 9043 |
| 9042 ss->handshake = ssl_GatherRecord1stHandshake; | 9044 ss->handshake = ssl_GatherRecord1stHandshake; |
| 9043 ss->ssl3.channelID = channelID; | 9045 ss->ssl3.channelID = channelID; |
| 9044 ss->ssl3.channelIDPub = channelIDPub; | 9046 ss->ssl3.channelIDPub = channelIDPub; |
| 9045 | 9047 |
| 9046 return SECSuccess; | 9048 return SECSuccess; |
| 9047 } | 9049 } |
| 9048 | 9050 |
| 9051 /* called from ssl3_SendFinished | |
| 9052 * | |
| 9053 * Caller must already hold the SpecReadLock. (wish we could assert that!). | |
| 9054 * This function is simply a debugging aid and therefore does not return a | |
| 9055 * SECStatus. */ | |
| 9056 static void | |
| 9057 ssl3_RecordKeyLog(sslSocket *ss) | |
| 9058 { | |
| 9059 sslSessionID *sid; | |
| 9060 SECStatus rv; | |
| 9061 SECItem *keyData; | |
| 9062 char buf[14 /* "CLIENT_RANDOM " */ + | |
| 9063 SSL3_RANDOM_LENGTH*2 /* client_random */ + | |
| 9064 1 /* " " */ + | |
| 9065 48*2 /* master secret */ + | |
| 9066 1 /* new line */]; | |
| 9067 unsigned int j; | |
| 9068 | |
| 9069 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | |
| 9070 | |
| 9071 sid = ss->sec.ci.sid; | |
| 9072 | |
| 9073 if (!ssl_keylog_iob) | |
| 9074 return; | |
| 9075 | |
| 9076 rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret); | |
| 9077 if (rv != SECSuccess) | |
| 9078 return; | |
| 9079 | |
| 9080 ssl_GetSpecReadLock(ss); | |
| 9081 | |
| 9082 /* keyData does not need to be freed. */ | |
| 9083 keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret); | |
| 9084 if (!keyData || !keyData->data || keyData->len != 48) { | |
| 9085 ssl_ReleaseSpecReadLock(ss); | |
| 9086 return; | |
| 9087 } | |
| 9088 | |
| 9089 /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ | |
| 9090 | |
| 9091 /* There could be multiple, concurrent writers to the | |
| 9092 * keylog, so we have to do everything in a single call to | |
| 9093 * fwrite. */ | |
| 9094 | |
| 9095 memcpy(buf, "CLIENT_RANDOM ", 14); | |
| 9096 j = 14; | |
| 9097 hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); | |
| 9098 j += SSL3_RANDOM_LENGTH*2; | |
| 9099 buf[j++] = ' '; | |
| 9100 hexEncode(buf + j, keyData->data, 48); | |
| 9101 j += 48*2; | |
| 9102 buf[j++] = '\n'; | |
| 9103 | |
| 9104 PORT_Assert(j == sizeof(buf)); | |
| 9105 | |
| 9106 ssl_ReleaseSpecReadLock(ss); | |
| 9107 | |
| 9108 if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1) | |
| 9109 return; | |
| 9110 fflush(ssl_keylog_iob); | |
| 9111 return; | |
| 9112 } | |
| 9113 | |
| 9049 /* called from ssl3_HandleServerHelloDone | 9114 /* called from ssl3_HandleServerHelloDone |
| 9050 * ssl3_HandleClientHello | 9115 * ssl3_HandleClientHello |
| 9051 * ssl3_HandleFinished | 9116 * ssl3_HandleFinished |
| 9052 */ | 9117 */ |
| 9053 static SECStatus | 9118 static SECStatus |
| 9054 ssl3_SendFinished(sslSocket *ss, PRInt32 flags) | 9119 ssl3_SendFinished(sslSocket *ss, PRInt32 flags) |
| 9055 { | 9120 { |
| 9056 ssl3CipherSpec *cwSpec; | 9121 ssl3CipherSpec *cwSpec; |
| 9057 PRBool isTLS; | 9122 PRBool isTLS; |
| 9058 PRBool isServer = ss->sec.isServer; | 9123 PRBool isServer = ss->sec.isServer; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9100 if (rv != SECSuccess) | 9165 if (rv != SECSuccess) |
| 9101 goto fail; /* err set by AppendHandshake. */ | 9166 goto fail; /* err set by AppendHandshake. */ |
| 9102 rv = ssl3_AppendHandshake(ss, &hashes, sizeof hashes); | 9167 rv = ssl3_AppendHandshake(ss, &hashes, sizeof hashes); |
| 9103 if (rv != SECSuccess) | 9168 if (rv != SECSuccess) |
| 9104 goto fail; /* err set by AppendHandshake. */ | 9169 goto fail; /* err set by AppendHandshake. */ |
| 9105 } | 9170 } |
| 9106 rv = ssl3_FlushHandshake(ss, flags); | 9171 rv = ssl3_FlushHandshake(ss, flags); |
| 9107 if (rv != SECSuccess) { | 9172 if (rv != SECSuccess) { |
| 9108 goto fail; /* error code set by ssl3_FlushHandshake */ | 9173 goto fail; /* error code set by ssl3_FlushHandshake */ |
| 9109 } | 9174 } |
| 9175 | |
| 9176 ssl3_RecordKeyLog(ss); | |
| 9177 | |
| 9110 return SECSuccess; | 9178 return SECSuccess; |
| 9111 | 9179 |
| 9112 fail: | 9180 fail: |
| 9113 return rv; | 9181 return rv; |
| 9114 } | 9182 } |
| 9115 | 9183 |
| 9116 /* wrap the master secret, and put it into the SID. | 9184 /* wrap the master secret, and put it into the SID. |
| 9117 * Caller holds the Spec read lock. | 9185 * Caller holds the Spec read lock. |
| 9118 */ | 9186 */ |
| 9119 SECStatus | 9187 SECStatus |
| (...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10626 PORT_Free(ss->ssl3.hs.recvdFragments.buf); | 10694 PORT_Free(ss->ssl3.hs.recvdFragments.buf); |
| 10627 } | 10695 } |
| 10628 } | 10696 } |
| 10629 | 10697 |
| 10630 ss->ssl3.initialized = PR_FALSE; | 10698 ss->ssl3.initialized = PR_FALSE; |
| 10631 | 10699 |
| 10632 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | 10700 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 10633 } | 10701 } |
| 10634 | 10702 |
| 10635 /* End of ssl3con.c */ | 10703 /* End of ssl3con.c */ |
| OLD | NEW |