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