| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Key Derivation that doesn't use PKCS11 | 2 * Key Derivation that doesn't use PKCS11 |
| 3 * | 3 * |
| 4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
| 5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 7 | 7 |
| 8 #include "ssl.h" » /* prereq to sslimpl.h */ | 8 #include "ssl.h" /* prereq to sslimpl.h */ |
| 9 #include "certt.h"» /* prereq to sslimpl.h */ | 9 #include "certt.h" /* prereq to sslimpl.h */ |
| 10 #include "keythi.h"» /* prereq to sslimpl.h */ | 10 #include "keythi.h" /* prereq to sslimpl.h */ |
| 11 #include "sslimpl.h" | 11 #include "sslimpl.h" |
| 12 #ifndef NO_PKCS11_BYPASS | 12 #ifndef NO_PKCS11_BYPASS |
| 13 #include "blapi.h" | 13 #include "blapi.h" |
| 14 #endif | 14 #endif |
| 15 | 15 |
| 16 #include "keyhi.h" | 16 #include "keyhi.h" |
| 17 #include "pk11func.h" | 17 #include "pk11func.h" |
| 18 #include "secasn1.h" | 18 #include "secasn1.h" |
| 19 #include "cert.h" | 19 #include "cert.h" |
| 20 #include "secmodt.h" | 20 #include "secmodt.h" |
| 21 | 21 |
| 22 #include "sslproto.h" | 22 #include "sslproto.h" |
| 23 #include "sslerr.h" | 23 #include "sslerr.h" |
| 24 | 24 |
| 25 #ifndef NO_PKCS11_BYPASS | 25 #ifndef NO_PKCS11_BYPASS |
| 26 /* make this a macro! */ | 26 /* make this a macro! */ |
| 27 #ifdef NOT_A_MACRO | 27 #ifdef NOT_A_MACRO |
| 28 static void | 28 static void |
| 29 buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result, | 29 buildSSLKey(unsigned char *keyBlock, unsigned int keyLen, SECItem *result, |
| 30 const char * label) | 30 const char *label) |
| 31 { | 31 { |
| 32 result->type = siBuffer; | 32 result->type = siBuffer; |
| 33 result->data = keyBlock; | 33 result->data = keyBlock; |
| 34 result->len = keyLen; | 34 result->len = keyLen; |
| 35 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); | 35 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); |
| 36 } | 36 } |
| 37 #else | 37 #else |
| 38 #define buildSSLKey(keyBlock, keyLen, result, label) \ | 38 #define buildSSLKey(keyBlock, keyLen, result, label) \ |
| 39 { \ | 39 { \ |
| 40 (result)->type = siBuffer; \ | 40 (result)->type = siBuffer; \ |
| 41 (result)->data = keyBlock; \ | 41 (result)->data = keyBlock; \ |
| 42 (result)->len = keyLen; \ | 42 (result)->len = keyLen; \ |
| 43 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); \ | 43 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); \ |
| 44 } | 44 } |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 /* | 47 /* |
| 48 * SSL Key generation given pre master secret | 48 * SSL Key generation given pre master secret |
| 49 */ | 49 */ |
| 50 #ifndef NUM_MIXERS | 50 #ifndef NUM_MIXERS |
| 51 #define NUM_MIXERS 9 | 51 #define NUM_MIXERS 9 |
| 52 #endif | 52 #endif |
| 53 static const char * const mixers[NUM_MIXERS] = { | 53 static const char *const mixers[NUM_MIXERS] = { |
| 54 "A", | 54 "A", |
| 55 "BB", | 55 "BB", |
| 56 "CCC", | 56 "CCC", |
| 57 "DDDD", | 57 "DDDD", |
| 58 "EEEEE", | 58 "EEEEE", |
| 59 "FFFFFF", | 59 "FFFFFF", |
| 60 "GGGGGGG", | 60 "GGGGGGG", |
| 61 "HHHHHHHH", | 61 "HHHHHHHH", |
| 62 "IIIIIIIII" | 62 "IIIIIIIII" |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 | |
| 66 SECStatus | 65 SECStatus |
| 67 ssl3_KeyAndMacDeriveBypass( | 66 ssl3_KeyAndMacDeriveBypass( |
| 68 ssl3CipherSpec * pwSpec, | 67 ssl3CipherSpec *pwSpec, |
| 69 const unsigned char * cr, | 68 const unsigned char *cr, |
| 70 const unsigned char * sr, | 69 const unsigned char *sr, |
| 71 PRBool isTLS, | 70 PRBool isTLS, |
| 72 PRBool isExport) | 71 PRBool isExport) |
| 73 { | 72 { |
| 74 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; | 73 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; |
| 75 unsigned char * key_block = pwSpec->key_block; | 74 unsigned char *key_block = pwSpec->key_block; |
| 76 unsigned char * key_block2 = NULL; | 75 unsigned char *key_block2 = NULL; |
| 77 unsigned int block_bytes = 0; | 76 unsigned int block_bytes = 0; |
| 78 unsigned int block_needed = 0; | 77 unsigned int block_needed = 0; |
| 79 unsigned int i; | 78 unsigned int i; |
| 80 unsigned int keySize; /* actual size of cipher keys */ | 79 unsigned int keySize; /* actual size of cipher keys */ |
| 81 unsigned int effKeySize;»» /* effective size of cipher keys */ | 80 unsigned int effKeySize; /* effective size of cipher keys */ |
| 82 unsigned int macSize;» » /* size of MAC secret */ | 81 unsigned int macSize; /* size of MAC secret */ |
| 83 unsigned int IVSize;» » /* size of IV */ | 82 unsigned int IVSize; /* size of IV */ |
| 84 PRBool explicitIV = PR_FALSE; | 83 PRBool explicitIV = PR_FALSE; |
| 85 SECStatus rv = SECFailure; | 84 SECStatus rv = SECFailure; |
| 86 SECStatus status = SECSuccess; | 85 SECStatus status = SECSuccess; |
| 87 PRBool isFIPS = PR_FALSE; | 86 PRBool isFIPS = PR_FALSE; |
| 88 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; | 87 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; |
| 89 | 88 |
| 90 SECItem srcr; | 89 SECItem srcr; |
| 91 SECItem crsr; | 90 SECItem crsr; |
| 92 | 91 |
| 93 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; | 92 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; |
| 94 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; | 93 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
| 95 PRUint64 md5buf[22]; | 94 PRUint64 md5buf[22]; |
| 96 PRUint64 shabuf[40]; | 95 PRUint64 shabuf[40]; |
| 97 | 96 |
| 98 #define md5Ctx ((MD5Context *)md5buf) | 97 #define md5Ctx ((MD5Context *)md5buf) |
| 99 #define shaCtx ((SHA1Context *)shabuf) | 98 #define shaCtx ((SHA1Context *)shabuf) |
| 100 | 99 |
| 101 static const SECItem zed = { siBuffer, NULL, 0 }; | 100 static const SECItem zed = { siBuffer, NULL, 0 }; |
| 102 | 101 |
| 103 if (pwSpec->msItem.data == NULL || | 102 if (pwSpec->msItem.data == NULL || |
| 104 pwSpec->msItem.len != SSL3_MASTER_SECRET_LENGTH) { | 103 pwSpec->msItem.len != SSL3_MASTER_SECRET_LENGTH) { |
| 105 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 104 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 106 » return rv; | 105 return rv; |
| 107 } | 106 } |
| 108 | 107 |
| 109 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, | 108 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, |
| 110 pwSpec->msItem.len)); | 109 pwSpec->msItem.len)); |
| 111 | 110 |
| 112 /* figure out how much is needed */ | 111 /* figure out how much is needed */ |
| 113 macSize = pwSpec->mac_size; | 112 macSize = pwSpec->mac_size; |
| 114 keySize = cipher_def->key_size; | 113 keySize = cipher_def->key_size; |
| 115 effKeySize = cipher_def->secret_key_size; | 114 effKeySize = cipher_def->secret_key_size; |
| 116 IVSize = cipher_def->iv_size; | 115 IVSize = cipher_def->iv_size; |
| 117 if (keySize == 0) { | 116 if (keySize == 0) { |
| 118 » effKeySize = IVSize = 0; /* only MACing */ | 117 effKeySize = IVSize = 0; /* only MACing */ |
| 119 } | 118 } |
| 120 if (cipher_def->type == type_block && | 119 if (cipher_def->type == type_block && |
| 121 » pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { | 120 pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { |
| 122 » /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ | 121 /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ |
| 123 » explicitIV = PR_TRUE; | 122 explicitIV = PR_TRUE; |
| 124 } | 123 } |
| 125 block_needed = | 124 block_needed = |
| 126 » 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * IVSize)); | 125 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * IVSize)); |
| 127 | 126 |
| 128 /* | 127 /* |
| 129 * clear out our returned keys so we can recover on failure | 128 * clear out our returned keys so we can recover on failure |
| 130 */ | 129 */ |
| 131 pwSpec->client.write_key_item = zed; | 130 pwSpec->client.write_key_item = zed; |
| 132 pwSpec->client.write_mac_key_item = zed; | 131 pwSpec->client.write_mac_key_item = zed; |
| 133 pwSpec->server.write_key_item = zed; | 132 pwSpec->server.write_key_item = zed; |
| 134 pwSpec->server.write_mac_key_item = zed; | 133 pwSpec->server.write_mac_key_item = zed; |
| 135 | 134 |
| 136 /* initialize the server random, client random block */ | 135 /* initialize the server random, client random block */ |
| 137 srcr.type = siBuffer; | 136 srcr.type = siBuffer; |
| 138 srcr.data = srcrdata; | 137 srcr.data = srcrdata; |
| 139 srcr.len = sizeof srcrdata; | 138 srcr.len = sizeof srcrdata; |
| 140 PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH); | 139 PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH); |
| 141 PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH); | 140 PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH); |
| 142 | 141 |
| 143 /* initialize the client random, server random block */ | 142 /* initialize the client random, server random block */ |
| 144 crsr.type = siBuffer; | 143 crsr.type = siBuffer; |
| 145 crsr.data = crsrdata; | 144 crsr.data = crsrdata; |
| 146 crsr.len = sizeof crsrdata; | 145 crsr.len = sizeof crsrdata; |
| 147 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); | 146 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); |
| 148 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); | 147 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); |
| 149 PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len)); | 148 PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len)); |
| 150 | 149 |
| 151 /* | 150 /* |
| 152 * generate the key material: | 151 * generate the key material: |
| 153 */ | 152 */ |
| 154 if (isTLS) { | 153 if (isTLS) { |
| 155 » SECItem keyblk; | 154 SECItem keyblk; |
| 156 | 155 |
| 157 » keyblk.type = siBuffer; | 156 keyblk.type = siBuffer; |
| 158 » keyblk.data = key_block; | 157 keyblk.data = key_block; |
| 159 » keyblk.len = block_needed; | 158 keyblk.len = block_needed; |
| 160 | 159 |
| 161 » if (isTLS12) { | 160 if (isTLS12) { |
| 162 » status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem, | 161 status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem, |
| 163 » » » » "key expansion", &srcr, &keyblk, isFIPS); | 162 "key expansion", &srcr, &keyblk, isFIPS); |
| 164 » } else { | 163 } else { |
| 165 » status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk, | 164 status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk, |
| 166 » » » isFIPS); | 165 isFIPS); |
| 167 » } | 166 } |
| 168 » if (status != SECSuccess) { | 167 if (status != SECSuccess) { |
| 169 » goto key_and_mac_derive_fail; | 168 goto key_and_mac_derive_fail; |
| 170 » } | 169 } |
| 171 » block_bytes = keyblk.len; | 170 block_bytes = keyblk.len; |
| 172 } else { | 171 } else { |
| 173 » /* key_block = | 172 /* key_block = |
| 174 » * MD5(master_secret + SHA('A' + master_secret + | 173 * MD5(master_secret + SHA('A' + master_secret + |
| 175 » * ServerHello.random + ClientHello.random)) + | 174 * ServerHello.random + ClientHello.random)) + |
| 176 » * MD5(master_secret + SHA('BB' + master_secret + | 175 * MD5(master_secret + SHA('BB' + master_secret + |
| 177 » * ServerHello.random + ClientHello.random)) + | 176 * ServerHello.random + ClientHello.random)) + |
| 178 » * MD5(master_secret + SHA('CCC' + master_secret + | 177 * MD5(master_secret + SHA('CCC' + master_secret + |
| 179 » * ServerHello.random + ClientHello.random)) + | 178 * ServerHello.random + ClientHello.random)) + |
| 180 » * [...]; | 179 * [...]; |
| 181 » */ | 180 */ |
| 182 » unsigned int made = 0; | 181 unsigned int made = 0; |
| 183 » for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) { | 182 for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) { |
| 184 » unsigned int outLen; | 183 unsigned int outLen; |
| 185 » unsigned char sha_out[SHA1_LENGTH]; | 184 unsigned char sha_out[SHA1_LENGTH]; |
| 186 | 185 |
| 187 » SHA1_Begin(shaCtx); | 186 SHA1_Begin(shaCtx); |
| 188 » SHA1_Update(shaCtx, (unsigned char*)(mixers[i]), i+1); | 187 SHA1_Update(shaCtx, (unsigned char *)(mixers[i]), i + 1); |
| 189 » SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len); | 188 SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len); |
| 190 » SHA1_Update(shaCtx, srcr.data, srcr.len); | 189 SHA1_Update(shaCtx, srcr.data, srcr.len); |
| 191 » SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); | 190 SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); |
| 192 » PORT_Assert(outLen == SHA1_LENGTH); | 191 PORT_Assert(outLen == SHA1_LENGTH); |
| 193 | 192 |
| 194 » MD5_Begin(md5Ctx); | 193 MD5_Begin(md5Ctx); |
| 195 » MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len); | 194 MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len); |
| 196 » MD5_Update(md5Ctx, sha_out, outLen); | 195 MD5_Update(md5Ctx, sha_out, outLen); |
| 197 » MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); | 196 MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); |
| 198 » PORT_Assert(outLen == MD5_LENGTH); | 197 PORT_Assert(outLen == MD5_LENGTH); |
| 199 » made += MD5_LENGTH; | 198 made += MD5_LENGTH; |
| 200 » } | 199 } |
| 201 » block_bytes = made; | 200 block_bytes = made; |
| 202 } | 201 } |
| 203 PORT_Assert(block_bytes >= block_needed); | 202 PORT_Assert(block_bytes >= block_needed); |
| 204 PORT_Assert(block_bytes <= sizeof pwSpec->key_block); | 203 PORT_Assert(block_bytes <= sizeof pwSpec->key_block); |
| 205 PRINT_BUF(100, (NULL, "key block", key_block, block_bytes)); | 204 PRINT_BUF(100, (NULL, "key block", key_block, block_bytes)); |
| 206 | 205 |
| 207 /* | 206 /* |
| 208 * Put the key material where it goes. | 207 * Put the key material where it goes. |
| 209 */ | 208 */ |
| 210 key_block2 = key_block + block_bytes; | 209 key_block2 = key_block + block_bytes; |
| 211 i = 0;» » » /* now shows how much consumed */ | 210 i = 0; /* now shows how much consumed */ |
| 212 | 211 |
| 213 /* | 212 /* |
| 214 * The key_block is partitioned as follows: | 213 * The key_block is partitioned as follows: |
| 215 * client_write_MAC_secret[CipherSpec.hash_size] | 214 * client_write_MAC_secret[CipherSpec.hash_size] |
| 216 */ | 215 */ |
| 217 buildSSLKey(&key_block[i],macSize, &pwSpec->client.write_mac_key_item, \ | 216 buildSSLKey(&key_block[i], macSize, &pwSpec->client.write_mac_key_item, |
| 218 "Client Write MAC Secret"); | 217 "Client Write MAC Secret"); |
| 219 i += macSize; | 218 i += macSize; |
| 220 | 219 |
| 221 /* | 220 /* |
| 222 * server_write_MAC_secret[CipherSpec.hash_size] | 221 * server_write_MAC_secret[CipherSpec.hash_size] |
| 223 */ | 222 */ |
| 224 buildSSLKey(&key_block[i],macSize, &pwSpec->server.write_mac_key_item, \ | 223 buildSSLKey(&key_block[i], macSize, &pwSpec->server.write_mac_key_item, |
| 225 "Server Write MAC Secret"); | 224 "Server Write MAC Secret"); |
| 226 i += macSize; | 225 i += macSize; |
| 227 | 226 |
| 228 if (!keySize) { | 227 if (!keySize) { |
| 229 » /* only MACing */ | 228 /* only MACing */ |
| 230 » buildSSLKey(NULL, 0, &pwSpec->client.write_key_item, \ | 229 buildSSLKey(NULL, 0, &pwSpec->client.write_key_item, |
| 231 » "Client Write Key (MAC only)"); | 230 "Client Write Key (MAC only)"); |
| 232 » buildSSLKey(NULL, 0, &pwSpec->server.write_key_item, \ | 231 buildSSLKey(NULL, 0, &pwSpec->server.write_key_item, |
| 233 » "Server Write Key (MAC only)"); | 232 "Server Write Key (MAC only)"); |
| 234 » buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item, \ | 233 buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item, |
| 235 » "Client Write IV (MAC only)"); | 234 "Client Write IV (MAC only)"); |
| 236 » buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item, \ | 235 buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item, |
| 237 » "Server Write IV (MAC only)"); | 236 "Server Write IV (MAC only)"); |
| 238 } else if (!isExport) { | 237 } else if (!isExport) { |
| 239 » /* | 238 /* |
| 240 » ** Generate Domestic write keys and IVs. | 239 ** Generate Domestic write keys and IVs. |
| 241 » ** client_write_key[CipherSpec.key_material] | 240 ** client_write_key[CipherSpec.key_material] |
| 242 » */ | 241 */ |
| 243 » buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item, \ | 242 buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item, |
| 244 » "Domestic Client Write Key"); | 243 "Domestic Client Write Key"); |
| 245 » i += keySize; | 244 i += keySize; |
| 246 | 245 |
| 247 » /* | 246 /* |
| 248 » ** server_write_key[CipherSpec.key_material] | 247 ** server_write_key[CipherSpec.key_material] |
| 249 » */ | 248 */ |
| 250 » buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, \ | 249 buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, |
| 251 » "Domestic Server Write Key"); | 250 "Domestic Server Write Key"); |
| 252 » i += keySize; | 251 i += keySize; |
| 253 | 252 |
| 254 » if (IVSize > 0) { | 253 if (IVSize > 0) { |
| 255 » if (explicitIV) { | 254 if (explicitIV) { |
| 256 » » static unsigned char zero_block[32]; | 255 static unsigned char zero_block[32]; |
| 257 » » PORT_Assert(IVSize <= sizeof zero_block); | 256 PORT_Assert(IVSize <= sizeof zero_block); |
| 258 » » buildSSLKey(&zero_block[0], IVSize, \ | 257 buildSSLKey(&zero_block[0], IVSize, |
| 259 » » » &pwSpec->client.write_iv_item, \ | 258 &pwSpec->client.write_iv_item, |
| 260 » » » "Domestic Client Write IV"); | 259 "Domestic Client Write IV"); |
| 261 » » buildSSLKey(&zero_block[0], IVSize, \ | 260 buildSSLKey(&zero_block[0], IVSize, |
| 262 » » » &pwSpec->server.write_iv_item, \ | 261 &pwSpec->server.write_iv_item, |
| 263 » » » "Domestic Server Write IV"); | 262 "Domestic Server Write IV"); |
| 264 » } else { | 263 } else { |
| 265 » » /* | 264 /* |
| 266 » » ** client_write_IV[CipherSpec.IV_size] | 265 ** client_write_IV[CipherSpec.IV_size] |
| 267 » » */ | 266 */ |
| 268 » » buildSSLKey(&key_block[i], IVSize, \ | 267 buildSSLKey(&key_block[i], IVSize, |
| 269 » » » &pwSpec->client.write_iv_item, \ | 268 &pwSpec->client.write_iv_item, |
| 270 » » » "Domestic Client Write IV"); | 269 "Domestic Client Write IV"); |
| 271 » » i += IVSize; | 270 i += IVSize; |
| 272 | 271 |
| 273 » » /* | 272 /* |
| 274 » » ** server_write_IV[CipherSpec.IV_size] | 273 ** server_write_IV[CipherSpec.IV_size] |
| 275 » » */ | 274 */ |
| 276 » » buildSSLKey(&key_block[i], IVSize, \ | 275 buildSSLKey(&key_block[i], IVSize, |
| 277 » » » &pwSpec->server.write_iv_item, \ | 276 &pwSpec->server.write_iv_item, |
| 278 » » » "Domestic Server Write IV"); | 277 "Domestic Server Write IV"); |
| 279 » » i += IVSize; | 278 i += IVSize; |
| 280 » } | 279 } |
| 281 » } | 280 } |
| 282 » PORT_Assert(i <= block_bytes); | 281 PORT_Assert(i <= block_bytes); |
| 283 } else if (!isTLS) { | 282 } else if (!isTLS) { |
| 284 » /* | 283 /* |
| 285 » ** Generate SSL3 Export write keys and IVs. | 284 ** Generate SSL3 Export write keys and IVs. |
| 286 » */ | 285 */ |
| 287 » unsigned int outLen; | 286 unsigned int outLen; |
| 288 | 287 |
| 289 » /* | 288 /* |
| 290 » ** client_write_key[CipherSpec.key_material] | 289 ** client_write_key[CipherSpec.key_material] |
| 291 » ** final_client_write_key = MD5(client_write_key + | 290 ** final_client_write_key = MD5(client_write_key + |
| 292 » ** ClientHello.random + ServerHello.random); | 291 ** ClientHello.random + ServerHello.random); |
| 293 » */ | 292 */ |
| 294 » MD5_Begin(md5Ctx); | 293 MD5_Begin(md5Ctx); |
| 295 » MD5_Update(md5Ctx, &key_block[i], effKeySize); | 294 MD5_Update(md5Ctx, &key_block[i], effKeySize); |
| 296 » MD5_Update(md5Ctx, crsr.data, crsr.len); | 295 MD5_Update(md5Ctx, crsr.data, crsr.len); |
| 297 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 296 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
| 298 » i += effKeySize; | 297 i += effKeySize; |
| 299 » buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \ | 298 buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, |
| 300 » "SSL3 Export Client Write Key"); | 299 "SSL3 Export Client Write Key"); |
| 301 » key_block2 += keySize; | 300 key_block2 += keySize; |
| 302 | 301 |
| 303 » /* | 302 /* |
| 304 » ** server_write_key[CipherSpec.key_material] | 303 ** server_write_key[CipherSpec.key_material] |
| 305 » ** final_server_write_key = MD5(server_write_key + | 304 ** final_server_write_key = MD5(server_write_key + |
| 306 » ** ServerHello.random + ClientHello.random); | 305 ** ServerHello.random + ClientHello.random); |
| 307 » */ | 306 */ |
| 308 » MD5_Begin(md5Ctx); | 307 MD5_Begin(md5Ctx); |
| 309 » MD5_Update(md5Ctx, &key_block[i], effKeySize); | 308 MD5_Update(md5Ctx, &key_block[i], effKeySize); |
| 310 » MD5_Update(md5Ctx, srcr.data, srcr.len); | 309 MD5_Update(md5Ctx, srcr.data, srcr.len); |
| 311 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 310 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
| 312 » i += effKeySize; | 311 i += effKeySize; |
| 313 » buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \ | 312 buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, |
| 314 » "SSL3 Export Server Write Key"); | 313 "SSL3 Export Server Write Key"); |
| 315 » key_block2 += keySize; | 314 key_block2 += keySize; |
| 316 » PORT_Assert(i <= block_bytes); | 315 PORT_Assert(i <= block_bytes); |
| 317 | 316 |
| 318 » if (IVSize) { | 317 if (IVSize) { |
| 319 » /* | 318 /* |
| 320 » ** client_write_IV = | 319 ** client_write_IV = |
| 321 » **» MD5(ClientHello.random + ServerHello.random); | 320 ** MD5(ClientHello.random + ServerHello.random); |
| 322 » */ | 321 */ |
| 323 » MD5_Begin(md5Ctx); | 322 MD5_Begin(md5Ctx); |
| 324 » MD5_Update(md5Ctx, crsr.data, crsr.len); | 323 MD5_Update(md5Ctx, crsr.data, crsr.len); |
| 325 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 324 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
| 326 » buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item, \ | 325 buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item, |
| 327 » "SSL3 Export Client Write IV"); | 326 "SSL3 Export Client Write IV"); |
| 328 » key_block2 += IVSize; | 327 key_block2 += IVSize; |
| 329 | 328 |
| 330 » /* | 329 /* |
| 331 » ** server_write_IV = | 330 ** server_write_IV = |
| 332 » **» MD5(ServerHello.random + ClientHello.random); | 331 ** MD5(ServerHello.random + ClientHello.random); |
| 333 » */ | 332 */ |
| 334 » MD5_Begin(md5Ctx); | 333 MD5_Begin(md5Ctx); |
| 335 » MD5_Update(md5Ctx, srcr.data, srcr.len); | 334 MD5_Update(md5Ctx, srcr.data, srcr.len); |
| 336 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 335 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
| 337 » buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item, \ | 336 buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item, |
| 338 » "SSL3 Export Server Write IV"); | 337 "SSL3 Export Server Write IV"); |
| 339 » key_block2 += IVSize; | 338 key_block2 += IVSize; |
| 340 » } | 339 } |
| 341 | 340 |
| 342 » PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); | 341 PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); |
| 343 } else { | 342 } else { |
| 344 » /* | 343 /* |
| 345 » ** Generate TLS Export write keys and IVs. | 344 ** Generate TLS Export write keys and IVs. |
| 346 » */ | 345 */ |
| 347 » SECItem secret ; | 346 SECItem secret; |
| 348 » SECItem keyblk ; | 347 SECItem keyblk; |
| 349 | 348 |
| 350 » secret.type = siBuffer; | 349 secret.type = siBuffer; |
| 351 » keyblk.type = siBuffer; | 350 keyblk.type = siBuffer; |
| 352 » /* | 351 /* |
| 353 » ** client_write_key[CipherSpec.key_material] | 352 ** client_write_key[CipherSpec.key_material] |
| 354 » ** final_client_write_key = PRF(client_write_key, | 353 ** final_client_write_key = PRF(client_write_key, |
| 355 » ** "client write key", | 354 ** "client write key", |
| 356 » ** client_random + server_random); | 355 ** client_random + server_random); |
| 357 » */ | 356 */ |
| 358 » secret.data = &key_block[i]; | 357 secret.data = &key_block[i]; |
| 359 » secret.len = effKeySize; | 358 secret.len = effKeySize; |
| 360 » i += effKeySize; | 359 i += effKeySize; |
| 361 » keyblk.data = key_block2; | 360 keyblk.data = key_block2; |
| 362 » keyblk.len = keySize; | 361 keyblk.len = keySize; |
| 363 » status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS); | 362 status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS); |
| 364 » if (status != SECSuccess) { | 363 if (status != SECSuccess) { |
| 365 » goto key_and_mac_derive_fail; | 364 goto key_and_mac_derive_fail; |
| 366 » } | 365 } |
| 367 » buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \ | 366 buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, |
| 368 » "TLS Export Client Write Key"); | 367 "TLS Export Client Write Key"); |
| 369 » key_block2 += keySize; | 368 key_block2 += keySize; |
| 370 | 369 |
| 371 » /* | 370 /* |
| 372 » ** server_write_key[CipherSpec.key_material] | 371 ** server_write_key[CipherSpec.key_material] |
| 373 » ** final_server_write_key = PRF(server_write_key, | 372 ** final_server_write_key = PRF(server_write_key, |
| 374 » ** "server write key", | 373 ** "server write key", |
| 375 » ** client_random + server_random); | 374 ** client_random + server_random); |
| 376 » */ | 375 */ |
| 377 » secret.data = &key_block[i]; | 376 secret.data = &key_block[i]; |
| 378 » secret.len = effKeySize; | 377 secret.len = effKeySize; |
| 379 » i += effKeySize; | 378 i += effKeySize; |
| 380 » keyblk.data = key_block2; | 379 keyblk.data = key_block2; |
| 381 » keyblk.len = keySize; | 380 keyblk.len = keySize; |
| 382 » status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS); | 381 status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS); |
| 383 » if (status != SECSuccess) { | 382 if (status != SECSuccess) { |
| 384 » goto key_and_mac_derive_fail; | 383 goto key_and_mac_derive_fail; |
| 385 » } | 384 } |
| 386 » buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \ | 385 buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, |
| 387 » "TLS Export Server Write Key"); | 386 "TLS Export Server Write Key"); |
| 388 » key_block2 += keySize; | 387 key_block2 += keySize; |
| 389 | 388 |
| 390 » /* | 389 /* |
| 391 » ** iv_block = PRF("", "IV block", client_random + server_random); | 390 ** iv_block = PRF("", "IV block", client_random + server_random); |
| 392 » ** client_write_IV[SecurityParameters.IV_size] | 391 ** client_write_IV[SecurityParameters.IV_size] |
| 393 » ** server_write_IV[SecurityParameters.IV_size] | 392 ** server_write_IV[SecurityParameters.IV_size] |
| 394 » */ | 393 */ |
| 395 » if (IVSize) { | 394 if (IVSize) { |
| 396 » secret.data = NULL; | 395 secret.data = NULL; |
| 397 » secret.len = 0; | 396 secret.len = 0; |
| 398 » keyblk.data = key_block2; | 397 keyblk.data = key_block2; |
| 399 » keyblk.len = 2 * IVSize; | 398 keyblk.len = 2 * IVSize; |
| 400 » status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS); | 399 status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS); |
| 401 » if (status != SECSuccess) { | 400 if (status != SECSuccess) { |
| 402 » » goto key_and_mac_derive_fail; | 401 goto key_and_mac_derive_fail; |
| 403 » } | 402 } |
| 404 » buildSSLKey(key_block2, IVSize, \ | 403 buildSSLKey(key_block2, IVSize, |
| 405 » &pwSpec->client.write_iv_item, \ | 404 &pwSpec->client.write_iv_item, |
| 406 » » » "TLS Export Client Write IV"); | 405 "TLS Export Client Write IV"); |
| 407 » buildSSLKey(key_block2 + IVSize, IVSize, \ | 406 buildSSLKey(key_block2 + IVSize, IVSize, |
| 408 » &pwSpec->server.write_iv_item, \ | 407 &pwSpec->server.write_iv_item, |
| 409 » » » "TLS Export Server Write IV"); | 408 "TLS Export Server Write IV"); |
| 410 » key_block2 += 2 * IVSize; | 409 key_block2 += 2 * IVSize; |
| 411 » } | 410 } |
| 412 » PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); | 411 PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); |
| 413 } | 412 } |
| 414 rv = SECSuccess; | 413 rv = SECSuccess; |
| 415 | 414 |
| 416 key_and_mac_derive_fail: | 415 key_and_mac_derive_fail: |
| 417 | 416 |
| 418 MD5_DestroyContext(md5Ctx, PR_FALSE); | 417 MD5_DestroyContext(md5Ctx, PR_FALSE); |
| 419 SHA1_DestroyContext(shaCtx, PR_FALSE); | 418 SHA1_DestroyContext(shaCtx, PR_FALSE); |
| 420 | 419 |
| 421 if (rv != SECSuccess) { | 420 if (rv != SECSuccess) { |
| 422 » PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); | 421 PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
| 423 } | 422 } |
| 424 | 423 |
| 425 return rv; | 424 return rv; |
| 426 } | 425 } |
| 427 | 426 |
| 428 | |
| 429 /* derive the Master Secret from the PMS */ | 427 /* derive the Master Secret from the PMS */ |
| 430 /* Presently, this is only done wtih RSA PMS, and only on the server side, | 428 /* Presently, this is only done wtih RSA PMS, and only on the server side, |
| 431 * so isRSA is always true. | 429 * so isRSA is always true. |
| 432 */ | 430 */ |
| 433 SECStatus | 431 SECStatus |
| 434 ssl3_MasterSecretDeriveBypass( | 432 ssl3_MasterSecretDeriveBypass( |
| 435 ssl3CipherSpec * pwSpec, | 433 ssl3CipherSpec *pwSpec, |
| 436 const unsigned char * cr, | 434 const unsigned char *cr, |
| 437 const unsigned char * sr, | 435 const unsigned char *sr, |
| 438 const SECItem * pms, | 436 const SECItem *pms, |
| 439 PRBool isTLS, | 437 PRBool isTLS, |
| 440 PRBool isRSA) | 438 PRBool isRSA) |
| 441 { | 439 { |
| 442 unsigned char * key_block = pwSpec->key_block; | 440 unsigned char *key_block = pwSpec->key_block; |
| 443 SECStatus rv = SECSuccess; | 441 SECStatus rv = SECSuccess; |
| 444 PRBool isFIPS = PR_FALSE; | 442 PRBool isFIPS = PR_FALSE; |
| 445 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; | 443 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; |
| 446 | 444 |
| 447 SECItem crsr; | 445 SECItem crsr; |
| 448 | 446 |
| 449 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; | 447 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
| 450 PRUint64 md5buf[22]; | 448 PRUint64 md5buf[22]; |
| 451 PRUint64 shabuf[40]; | 449 PRUint64 shabuf[40]; |
| 452 | 450 |
| 453 #define md5Ctx ((MD5Context *)md5buf) | 451 #define md5Ctx ((MD5Context *)md5buf) |
| 454 #define shaCtx ((SHA1Context *)shabuf) | 452 #define shaCtx ((SHA1Context *)shabuf) |
| 455 | 453 |
| 456 /* first do the consistancy checks */ | 454 /* first do the consistancy checks */ |
| 457 if (isRSA) { | 455 if (isRSA) { |
| 458 » PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH); | 456 PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH); |
| 459 » if (pms->len != SSL3_RSA_PMS_LENGTH) { | 457 if (pms->len != SSL3_RSA_PMS_LENGTH) { |
| 460 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 458 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 461 » return SECFailure; | 459 return SECFailure; |
| 462 » } | 460 } |
| 463 » /* caller must test PMS version for rollback */ | 461 /* caller must test PMS version for rollback */ |
| 464 } | 462 } |
| 465 | 463 |
| 466 /* initialize the client random, server random block */ | 464 /* initialize the client random, server random block */ |
| 467 crsr.type = siBuffer; | 465 crsr.type = siBuffer; |
| 468 crsr.data = crsrdata; | 466 crsr.data = crsrdata; |
| 469 crsr.len = sizeof crsrdata; | 467 crsr.len = sizeof crsrdata; |
| 470 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); | 468 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); |
| 471 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); | 469 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); |
| 472 PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); | 470 PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); |
| 473 | 471 |
| 474 /* finally do the key gen */ | 472 /* finally do the key gen */ |
| 475 if (isTLS) { | 473 if (isTLS) { |
| 476 » SECItem master = { siBuffer, NULL, 0 }; | 474 SECItem master = { siBuffer, NULL, 0 }; |
| 477 | 475 |
| 478 » master.data = key_block; | 476 master.data = key_block; |
| 479 » master.len = SSL3_MASTER_SECRET_LENGTH; | 477 master.len = SSL3_MASTER_SECRET_LENGTH; |
| 480 | 478 |
| 481 » if (isTLS12) { | 479 if (isTLS12) { |
| 482 » rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr, | 480 rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr, |
| 483 » » » &master, isFIPS); | 481 &master, isFIPS); |
| 484 » } else { | 482 } else { |
| 485 » rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS); | 483 rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS); |
| 486 » } | 484 } |
| 487 » if (rv != SECSuccess) { | 485 if (rv != SECSuccess) { |
| 488 » PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); | 486 PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
| 489 » } | 487 } |
| 490 } else { | 488 } else { |
| 491 » int i; | 489 int i; |
| 492 » unsigned int made = 0; | 490 unsigned int made = 0; |
| 493 » for (i = 0; i < 3; i++) { | 491 for (i = 0; i < 3; i++) { |
| 494 » unsigned int outLen; | 492 unsigned int outLen; |
| 495 » unsigned char sha_out[SHA1_LENGTH]; | 493 unsigned char sha_out[SHA1_LENGTH]; |
| 496 | 494 |
| 497 » SHA1_Begin(shaCtx); | 495 SHA1_Begin(shaCtx); |
| 498 » SHA1_Update(shaCtx, (unsigned char*) mixers[i], i+1); | 496 SHA1_Update(shaCtx, (unsigned char *)mixers[i], i + 1); |
| 499 » SHA1_Update(shaCtx, pms->data, pms->len); | 497 SHA1_Update(shaCtx, pms->data, pms->len); |
| 500 » SHA1_Update(shaCtx, crsr.data, crsr.len); | 498 SHA1_Update(shaCtx, crsr.data, crsr.len); |
| 501 » SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); | 499 SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); |
| 502 » PORT_Assert(outLen == SHA1_LENGTH); | 500 PORT_Assert(outLen == SHA1_LENGTH); |
| 503 | 501 |
| 504 » MD5_Begin(md5Ctx); | 502 MD5_Begin(md5Ctx); |
| 505 » MD5_Update(md5Ctx, pms->data, pms->len); | 503 MD5_Update(md5Ctx, pms->data, pms->len); |
| 506 » MD5_Update(md5Ctx, sha_out, outLen); | 504 MD5_Update(md5Ctx, sha_out, outLen); |
| 507 » MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); | 505 MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); |
| 508 » PORT_Assert(outLen == MD5_LENGTH); | 506 PORT_Assert(outLen == MD5_LENGTH); |
| 509 » made += outLen; | 507 made += outLen; |
| 510 » } | 508 } |
| 511 } | 509 } |
| 512 | 510 |
| 513 /* store the results */ | 511 /* store the results */ |
| 514 PORT_Memcpy(pwSpec->raw_master_secret, key_block, | 512 PORT_Memcpy(pwSpec->raw_master_secret, key_block, |
| 515 » » SSL3_MASTER_SECRET_LENGTH); | 513 SSL3_MASTER_SECRET_LENGTH); |
| 516 pwSpec->msItem.data = pwSpec->raw_master_secret; | 514 pwSpec->msItem.data = pwSpec->raw_master_secret; |
| 517 pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; | 515 pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; |
| 518 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, | 516 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, |
| 519 pwSpec->msItem.len)); | 517 pwSpec->msItem.len)); |
| 520 | 518 |
| 521 return rv; | 519 return rv; |
| 522 } | 520 } |
| 523 | 521 |
| 524 static SECStatus | 522 static SECStatus |
| 525 ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) | 523 ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) |
| 526 { SECStatus» rv; | 524 { |
| 527 PK11SymKey * ms = NULL; | 525 SECStatus rv; |
| 528 SECItem params = {siBuffer, NULL, 0}; | 526 PK11SymKey *ms = NULL; |
| 527 SECItem params = { siBuffer, NULL, 0 }; |
| 529 CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; | 528 CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; |
| 530 unsigned char rand[SSL3_RANDOM_LENGTH]; | 529 unsigned char rand[SSL3_RANDOM_LENGTH]; |
| 531 CK_VERSION pms_version; | 530 CK_VERSION pms_version; |
| 532 CK_MECHANISM_TYPE master_derive; | 531 CK_MECHANISM_TYPE master_derive; |
| 533 CK_MECHANISM_TYPE key_derive; | 532 CK_MECHANISM_TYPE key_derive; |
| 534 CK_FLAGS keyFlags; | 533 CK_FLAGS keyFlags; |
| 535 | 534 |
| 536 if (pms == NULL) | 535 if (pms == NULL) |
| 537 » return(SECFailure); | 536 return (SECFailure); |
| 538 | 537 |
| 539 PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); | 538 PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); |
| 540 | 539 |
| 541 if (isTLS) { | 540 if (isTLS) { |
| 542 » if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; | 541 if (isDH) |
| 543 » else master_derive = CKM_TLS_MASTER_KEY_DERIVE; | 542 master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 544 » key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; | 543 else |
| 545 » keyFlags = CKF_SIGN | CKF_VERIFY; | 544 master_derive = CKM_TLS_MASTER_KEY_DERIVE; |
| 545 key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; |
| 546 keyFlags = CKF_SIGN | CKF_VERIFY; |
| 546 } else { | 547 } else { |
| 547 » if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 548 if (isDH) |
| 548 » else master_derive = CKM_SSL3_MASTER_KEY_DERIVE; | 549 master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 549 » key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; | 550 else |
| 550 » keyFlags = 0; | 551 master_derive = CKM_SSL3_MASTER_KEY_DERIVE; |
| 552 key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; |
| 553 keyFlags = 0; |
| 551 } | 554 } |
| 552 | 555 |
| 553 master_params.pVersion = &pms_version; | 556 master_params.pVersion = &pms_version; |
| 554 master_params.RandomInfo.pClientRandom = rand; | 557 master_params.RandomInfo.pClientRandom = rand; |
| 555 master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; | 558 master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; |
| 556 master_params.RandomInfo.pServerRandom = rand; | 559 master_params.RandomInfo.pServerRandom = rand; |
| 557 master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; | 560 master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; |
| 558 | 561 |
| 559 params.data = (unsigned char *) &master_params; | 562 params.data = (unsigned char *)&master_params; |
| 560 params.len = sizeof master_params; | 563 params.len = sizeof master_params; |
| 561 | 564 |
| 562 ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, | 565 ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, |
| 563 » » » CKA_DERIVE, 0, keyFlags); | 566 CKA_DERIVE, 0, keyFlags); |
| 564 if (ms == NULL) | 567 if (ms == NULL) |
| 565 » return(SECFailure); | 568 return (SECFailure); |
| 566 | 569 |
| 567 rv = PK11_ExtractKeyValue(ms); | 570 rv = PK11_ExtractKeyValue(ms); |
| 568 *pcbp = (rv == SECSuccess); | 571 *pcbp = (rv == SECSuccess); |
| 569 PK11_FreeSymKey(ms); | 572 PK11_FreeSymKey(ms); |
| 570 | |
| 571 return(rv); | |
| 572 | 573 |
| 574 return (rv); |
| 573 } | 575 } |
| 574 #endif /* !NO_PKCS11_BYPASS */ | 576 #endif /* !NO_PKCS11_BYPASS */ |
| 575 | 577 |
| 576 /* Check the key exchange algorithm for each cipher in the list to see if | 578 /* Check the key exchange algorithm for each cipher in the list to see if |
| 577 * a master secret key can be extracted. If the KEA will use keys from the | 579 * a master secret key can be extracted. If the KEA will use keys from the |
| 578 * specified cert make sure the extract operation is attempted from the slot | 580 * specified cert make sure the extract operation is attempted from the slot |
| 579 * where the private key resides. | 581 * where the private key resides. |
| 580 * If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and | 582 * If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and |
| 581 * SECSuccess is returned. In all other cases but one (*pcanbypass) is | 583 * SECSuccess is returned. In all other cases but one (*pcanbypass) is |
| 582 * set to FALSE and SECFailure is returned. | 584 * set to FALSE and SECFailure is returned. |
| 583 * In that last case Derive() has been called successfully but the MS is null, | 585 * In that last case Derive() has been called successfully but the MS is null, |
| 584 * CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the | 586 * CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the |
| 585 * arguments were all valid but the slot cannot be bypassed. | 587 * arguments were all valid but the slot cannot be bypassed. |
| 586 */ | 588 */ |
| 587 | 589 |
| 588 /* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */ | 590 /* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */ |
| 589 | 591 |
| 590 SECStatus | 592 SECStatus |
| 591 SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, | 593 SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, |
| 592 » PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites, | 594 PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites, |
| 593 PRBool *pcanbypass, void *pwArg) | 595 PRBool *pcanbypass, void *pwArg) |
| 594 { | 596 { |
| 595 #ifdef NO_PKCS11_BYPASS | 597 #ifdef NO_PKCS11_BYPASS |
| 596 if (!pcanbypass) { | 598 if (!pcanbypass) { |
| 597 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 599 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 598 return SECFailure; | 600 return SECFailure; |
| 599 } | 601 } |
| 600 *pcanbypass = PR_FALSE; | 602 *pcanbypass = PR_FALSE; |
| 601 return SECSuccess; | 603 return SECSuccess; |
| 602 #else | 604 #else |
| 603 SECStatus» rv; | 605 SECStatus rv; |
| 604 int»» i; | 606 int i; |
| 605 PRUint16» suite; | 607 PRUint16 suite; |
| 606 PK11SymKey * pms = NULL; | 608 PK11SymKey *pms = NULL; |
| 607 SECKEYPublicKey * srvPubkey = NULL; | 609 SECKEYPublicKey *srvPubkey = NULL; |
| 608 KeyType» privKeytype; | 610 KeyType privKeytype; |
| 609 PK11SlotInfo * slot = NULL; | 611 PK11SlotInfo *slot = NULL; |
| 610 SECItem param; | 612 SECItem param; |
| 611 CK_VERSION » version; | 613 CK_VERSION version; |
| 612 CK_MECHANISM_TYPE mechanism_array[2]; | 614 CK_MECHANISM_TYPE mechanism_array[2]; |
| 613 SECItem enc_pms = {siBuffer, NULL, 0}; | 615 SECItem enc_pms = { siBuffer, NULL, 0 }; |
| 614 PRBool» isTLS = PR_FALSE; | 616 PRBool isTLS = PR_FALSE; |
| 615 SSLCipherSuiteInfo csdef; | 617 SSLCipherSuiteInfo csdef; |
| 616 PRBool» testrsa = PR_FALSE; | 618 PRBool testrsa = PR_FALSE; |
| 617 PRBool» testrsa_export = PR_FALSE; | 619 PRBool testrsa_export = PR_FALSE; |
| 618 PRBool» testecdh = PR_FALSE; | 620 PRBool testecdh = PR_FALSE; |
| 619 PRBool» testecdhe = PR_FALSE; | 621 PRBool testecdhe = PR_FALSE; |
| 620 #ifndef NSS_DISABLE_ECC | 622 #ifndef NSS_DISABLE_ECC |
| 621 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; | 623 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; |
| 622 #endif | 624 #endif |
| 623 | 625 |
| 624 if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { | 626 if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { |
| 625 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 627 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 626 return SECFailure; | 628 return SECFailure; |
| 627 } | 629 } |
| 628 | 630 |
| 629 srvPubkey = CERT_ExtractPublicKey(cert); | 631 srvPubkey = CERT_ExtractPublicKey(cert); |
| 630 if (!srvPubkey) | 632 if (!srvPubkey) |
| 631 return SECFailure; | 633 return SECFailure; |
| 632 » | 634 |
| 633 *pcanbypass = PR_TRUE; | 635 *pcanbypass = PR_TRUE; |
| 634 rv = SECFailure; | 636 rv = SECFailure; |
| 635 | 637 |
| 636 /* determine which KEAs to test */ | 638 /* determine which KEAs to test */ |
| 637 /* 0 (TLS_NULL_WITH_NULL_NULL) is used as a list terminator because | 639 /* 0 (TLS_NULL_WITH_NULL_NULL) is used as a list terminator because |
| 638 * SSL3 and TLS specs forbid negotiating that cipher suite number. | 640 * SSL3 and TLS specs forbid negotiating that cipher suite number. |
| 639 */ | 641 */ |
| 640 for (i=0; i < nsuites && (suite = *ciphersuites++) != 0; i++) { | 642 for (i = 0; i < nsuites && (suite = *ciphersuites++) != 0; i++) { |
| 641 » /* skip SSL2 cipher suites and ones NSS doesn't support */ | 643 /* skip SSL2 cipher suites and ones NSS doesn't support */ |
| 642 » if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess | 644 if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess |
| |
| 643 » || SSL_IS_SSL2_CIPHER(suite) ) | 645 SSL_IS_SSL2_CIPHER(suite)) |
| 644 » continue; | 646 continue; |
| 645 » switch (csdef.keaType) { | 647 switch (csdef.keaType) { |
| 646 » case ssl_kea_rsa: | 648 case ssl_kea_rsa: |
| 647 » switch (csdef.cipherSuite) { | 649 switch (csdef.cipherSuite) { |
| 648 » case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA: | 650 case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA: |
| 649 » case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA: | 651 case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA: |
| 650 » case TLS_RSA_EXPORT_WITH_RC4_40_MD5: | 652 case TLS_RSA_EXPORT_WITH_RC4_40_MD5: |
| 651 » case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5: | 653 case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5: |
| 652 » » testrsa_export = PR_TRUE; | 654 testrsa_export = PR_TRUE; |
| 653 » } | 655 } |
| 654 » if (!testrsa_export) | 656 if (!testrsa_export) |
| 655 » » testrsa = PR_TRUE; | 657 testrsa = PR_TRUE; |
| 656 » break; | 658 break; |
| 657 » case ssl_kea_ecdh: | 659 case ssl_kea_ecdh: |
| 658 » if (strcmp(csdef.keaTypeName, "ECDHE") == 0) /* ephemeral? */ | 660 if (strcmp(csdef.keaTypeName, "ECDHE") == 0) /* ephemeral? */ |
| 659 » » testecdhe = PR_TRUE; | 661 testecdhe = PR_TRUE; |
| 660 » else | 662 else |
| 661 » » testecdh = PR_TRUE; | 663 testecdh = PR_TRUE; |
| 662 » break; | 664 break; |
| 663 » case ssl_kea_dh: | 665 case ssl_kea_dh: |
| 664 » /* this is actually DHE */ | 666 /* this is actually DHE */ |
| 665 » default: | 667 default: |
| 666 » continue; | 668 continue; |
| 667 » } | 669 } |
| 668 } | 670 } |
| 669 | 671 |
| 670 /* For each protocol try to derive and extract an MS. | 672 /* For each protocol try to derive and extract an MS. |
| 671 * Failure of function any function except MS extract means | 673 * Failure of function any function except MS extract means |
| 672 * continue with the next cipher test. Stop testing when the list is | 674 * continue with the next cipher test. Stop testing when the list is |
| 673 * exhausted or when the first MS extract--not derive--fails. | 675 * exhausted or when the first MS extract--not derive--fails. |
| 674 */ | 676 */ |
| 675 privKeytype = SECKEY_GetPrivateKeyType(srvPrivkey); | 677 privKeytype = SECKEY_GetPrivateKeyType(srvPrivkey); |
| 676 protocolmask &= SSL_CBP_SSL3|SSL_CBP_TLS1_0; | 678 protocolmask &= SSL_CBP_SSL3 | SSL_CBP_TLS1_0; |
| 677 while (protocolmask) { | 679 while (protocolmask) { |
| 678 » if (protocolmask & SSL_CBP_SSL3) { | 680 if (protocolmask & SSL_CBP_SSL3) { |
| 679 » isTLS = PR_FALSE; | 681 isTLS = PR_FALSE; |
| 680 » protocolmask ^= SSL_CBP_SSL3; | 682 protocolmask ^= SSL_CBP_SSL3; |
| 681 » } else { | 683 } else { |
| 682 » isTLS = PR_TRUE; | 684 isTLS = PR_TRUE; |
| 683 » protocolmask ^= SSL_CBP_TLS1_0; | 685 protocolmask ^= SSL_CBP_TLS1_0; |
| 684 » } | 686 } |
| 685 | 687 |
| 686 » if (privKeytype == rsaKey && testrsa_export) { | 688 if (privKeytype == rsaKey && testrsa_export) { |
| 687 » if (PK11_GetPrivateModulusLen(srvPrivkey) > EXPORT_RSA_KEY_LENGTH) { | 689 if (PK11_GetPrivateModulusLen(srvPrivkey) > EXPORT_RSA_KEY_LENGTH) { |
| 688 » » *pcanbypass = PR_FALSE; | 690 *pcanbypass = PR_FALSE; |
| 689 » » rv = SECSuccess; | 691 rv = SECSuccess; |
| 690 » » break; | 692 break; |
| 691 » } else | 693 } else |
| 692 » » testrsa = PR_TRUE; | 694 testrsa = PR_TRUE; |
| 693 » } | 695 } |
| 694 » for (; privKeytype == rsaKey && testrsa; ) { | 696 for (; privKeytype == rsaKey && testrsa;) { |
| 695 » /* TLS_RSA */ | 697 /* TLS_RSA */ |
| 696 » unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; | 698 unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; |
| 697 » unsigned int outLen = 0; | 699 unsigned int outLen = 0; |
| 698 » CK_MECHANISM_TYPE target; | 700 CK_MECHANISM_TYPE target; |
| 699 » SECStatus» irv; | 701 SECStatus irv; |
| 700 » | 702 |
| 701 » mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN; | 703 mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN; |
| 702 » mechanism_array[1] = CKM_RSA_PKCS; | 704 mechanism_array[1] = CKM_RSA_PKCS; |
| 703 | 705 |
| 704 » slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); | 706 slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); |
| 705 » if (slot == NULL) { | 707 if (slot == NULL) { |
| 706 » » PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); | 708 PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); |
| 707 » » break; | 709 break; |
| 708 » } | 710 } |
| 709 | 711 |
| 710 » /* Generate the pre-master secret ... (client side) */ | 712 /* Generate the pre-master secret ... (client side) */ |
| 711 » version.major = 3 /*MSB(clientHelloVersion)*/; | 713 version.major = 3 /*MSB(clientHelloVersion)*/; |
| 712 » version.minor = 0 /*LSB(clientHelloVersion)*/; | 714 version.minor = 0 /*LSB(clientHelloVersion)*/; |
| 713 » param.data = (unsigned char *)&version; | 715 param.data = (unsigned char *)&version; |
| 714 » param.len = sizeof version; | 716 param.len = sizeof version; |
| 715 » pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwAr
g); | 717 pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwAr
g); |
| 716 » PK11_FreeSlot(slot); | 718 PK11_FreeSlot(slot); |
| 717 » if (!pms) | 719 if (!pms) |
| 718 » » break; | 720 break; |
| 719 » /* now wrap it */ | 721 /* now wrap it */ |
| 720 » enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); | 722 enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); |
| 721 » enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); | 723 enc_pms.data = (unsigned char *)PORT_Alloc(enc_pms.len); |
| 722 » if (enc_pms.data == NULL) { | 724 if (enc_pms.data == NULL) { |
| 723 » PORT_SetError(PR_OUT_OF_MEMORY_ERROR); | 725 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); |
| 724 » break; | 726 break; |
| 725 » } | 727 } |
| 726 » irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); | 728 irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); |
| 727 » if (irv != SECSuccess) | 729 if (irv != SECSuccess) |
| 728 » » break; | 730 break; |
| 729 » PK11_FreeSymKey(pms); | 731 PK11_FreeSymKey(pms); |
| 730 » pms = NULL; | 732 pms = NULL; |
| 731 » /* now do the server side--check the triple bypass first */ | 733 /* now do the server side--check the triple bypass first */ |
| 732 » rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, | 734 rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, |
| 733 » » » » sizeof rsaPmsBuf, | 735 sizeof rsaPmsBuf, |
| 734 » » » » (unsigned char *)enc_pms.data, | 736 (unsigned char *)enc_pms.data, |
| 735 » » » » enc_pms.len); | 737 enc_pms.len); |
| 736 » /* if decrypt worked we're done with the RSA test */ | 738 /* if decrypt worked we're done with the RSA test */ |
| 737 » if (rv == SECSuccess) { | 739 if (rv == SECSuccess) { |
| 738 » » *pcanbypass = PR_TRUE; | 740 *pcanbypass = PR_TRUE; |
| 739 » » break; | 741 break; |
| 740 » } | 742 } |
| 741 » /* check for fallback to double bypass */ | 743 /* check for fallback to double bypass */ |
| 742 » target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE | 744 target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE |
| 743 » » » : CKM_SSL3_MASTER_KEY_DERIVE; | 745 : CKM_SSL3_MASTER_KEY_DERIVE; |
| 744 » pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, | 746 pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, |
| 745 » » » » target, CKA_DERIVE, 0); | 747 target, CKA_DERIVE, 0); |
| 746 » rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); | 748 rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); |
| 747 » if (rv == SECSuccess && *pcanbypass == PR_FALSE) | 749 if (rv == SECSuccess && *pcanbypass == PR_FALSE) |
| 748 » » goto done; | 750 goto done; |
| 749 » break; | 751 break; |
| 750 » } | 752 } |
| 751 | 753 |
| 752 » /* Check for NULL to avoid double free. | 754 /* Check for NULL to avoid double free. |
| 753 » * SECItem_FreeItem sets data NULL in secitem.c#265 | 755 * SECItem_FreeItem sets data NULL in secitem.c#265 |
| 754 » */ | 756 */ |
| 755 » if (enc_pms.data != NULL) { | 757 if (enc_pms.data != NULL) { |
| 756 » SECITEM_FreeItem(&enc_pms, PR_FALSE); | 758 SECITEM_FreeItem(&enc_pms, PR_FALSE); |
| 757 } | 759 } |
| 758 #ifndef NSS_DISABLE_ECC | 760 #ifndef NSS_DISABLE_ECC |
| 759 » for (; (privKeytype == ecKey && ( testecdh || testecdhe)) || | 761 for (; (privKeytype == ecKey && (testecdh || testecdhe)) || |
| 760 » (privKeytype == rsaKey && testecdhe); ) { | 762 (privKeytype == rsaKey && testecdhe);) { |
| 761 » CK_MECHANISM_TYPE target; | 763 CK_MECHANISM_TYPE target; |
| 762 » SECKEYPublicKey *keapub = NULL; | 764 SECKEYPublicKey *keapub = NULL; |
| 763 » SECKEYPrivateKey *keapriv; | 765 SECKEYPrivateKey *keapriv; |
| 764 » SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ | 766 SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ |
| 765 » SECKEYPrivateKey *cpriv = NULL; | 767 SECKEYPrivateKey *cpriv = NULL; |
| 766 » SECKEYECParams *pecParams = NULL; | 768 SECKEYECParams *pecParams = NULL; |
| 767 | 769 |
| 768 » if (privKeytype == ecKey && testecdhe) { | 770 if (privKeytype == ecKey && testecdhe) { |
| 769 » » /* TLS_ECDHE_ECDSA */ | 771 /* TLS_ECDHE_ECDSA */ |
| 770 » » pecParams = &srvPubkey->u.ec.DEREncodedParams; | 772 pecParams = &srvPubkey->u.ec.DEREncodedParams; |
| 771 » } else if (privKeytype == rsaKey && testecdhe) { | 773 } else if (privKeytype == rsaKey && testecdhe) { |
| 772 » » /* TLS_ECDHE_RSA */ | 774 /* TLS_ECDHE_RSA */ |
| 773 » » ECName ec_curve; | 775 ECName ec_curve; |
| 774 » » int» » serverKeyStrengthInBits; | 776 int serverKeyStrengthInBits; |
| 775 » » int» » signatureKeyStrength; | 777 int signatureKeyStrength; |
| 776 » » int» » requiredECCbits; | 778 int requiredECCbits; |
| 777 | 779 |
| 778 » » /* find a curve of equivalent strength to the RSA key's */ | 780 /* find a curve of equivalent strength to the RSA key's */ |
| 779 » » requiredECCbits = PK11_GetPrivateModulusLen(srvPrivkey); | 781 requiredECCbits = PK11_GetPrivateModulusLen(srvPrivkey); |
| 780 » » if (requiredECCbits < 0) | 782 if (requiredECCbits < 0) |
| 781 » » break; | 783 break; |
| 782 » » requiredECCbits *= BPB; | 784 requiredECCbits *= BPB; |
| 783 » » serverKeyStrengthInBits = srvPubkey->u.rsa.modulus.len; | 785 serverKeyStrengthInBits = srvPubkey->u.rsa.modulus.len; |
| 784 » » if (srvPubkey->u.rsa.modulus.data[0] == 0) { | 786 if (srvPubkey->u.rsa.modulus.data[0] == 0) { |
| 785 » » serverKeyStrengthInBits--; | 787 serverKeyStrengthInBits--; |
| 786 » » } | 788 } |
| 787 » » /* convert to strength in bits */ | 789 /* convert to strength in bits */ |
| 788 » » serverKeyStrengthInBits *= BPB; | 790 serverKeyStrengthInBits *= BPB; |
| 789 | 791 |
| 790 » » signatureKeyStrength = | 792 signatureKeyStrength = |
| 791 » » SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); | 793 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); |
| 792 | 794 |
| 793 » » if ( requiredECCbits > signatureKeyStrength ) | 795 if (requiredECCbits > signatureKeyStrength) |
| 794 » » requiredECCbits = signatureKeyStrength; | 796 requiredECCbits = signatureKeyStrength; |
| 795 | 797 |
| 796 » » ec_curve = | 798 ec_curve = |
| 797 » » ssl3_GetCurveWithECKeyStrength( | 799 ssl3_GetCurveWithECKeyStrength( |
| 798 » » » » » ssl3_GetSupportedECCurveMask(NULL), | 800 ssl3_GetSupportedECCurveMask(NULL), |
| 799 » » » » » requiredECCbits); | 801 requiredECCbits); |
| 800 » » rv = ssl3_ECName2Params(NULL, ec_curve, &ecParams); | 802 rv = ssl3_ECName2Params(NULL, ec_curve, &ecParams); |
| 801 » » if (rv == SECFailure) { | 803 if (rv == SECFailure) { |
| 802 » » break; | 804 break; |
| 803 » » } | 805 } |
| 804 » » pecParams = &ecParams; | 806 pecParams = &ecParams; |
| 805 » } | 807 } |
| 806 | 808 |
| 807 » if (testecdhe) { | 809 if (testecdhe) { |
| 808 » » /* generate server's ephemeral keys */ | 810 /* generate server's ephemeral keys */ |
| 809 » » keapriv = SECKEY_CreateECPrivateKey(pecParams, &keapub, NULL); | 811 keapriv = SECKEY_CreateECPrivateKey(pecParams, &keapub, NULL); |
| 810 » » if (!keapriv || !keapub) { | 812 if (!keapriv || !keapub) { |
| 811 » » if (keapriv) | 813 if (keapriv) |
| 812 » » » SECKEY_DestroyPrivateKey(keapriv); | 814 SECKEY_DestroyPrivateKey(keapriv); |
| 813 » » if (keapub) | 815 if (keapub) |
| 814 » » » SECKEY_DestroyPublicKey(keapub); | 816 SECKEY_DestroyPublicKey(keapub); |
| 815 » » PORT_SetError(SEC_ERROR_KEYGEN_FAIL); | 817 PORT_SetError(SEC_ERROR_KEYGEN_FAIL); |
| 816 » » rv = SECFailure; | 818 rv = SECFailure; |
| 817 » » break; | 819 break; |
| 818 » » } | 820 } |
| 819 » } else { | 821 } else { |
| 820 » » /* TLS_ECDH_ECDSA */ | 822 /* TLS_ECDH_ECDSA */ |
| 821 » » keapub = srvPubkey; | 823 keapub = srvPubkey; |
| 822 » » keapriv = srvPrivkey; | 824 keapriv = srvPrivkey; |
| 823 » » pecParams = &srvPubkey->u.ec.DEREncodedParams; | 825 pecParams = &srvPubkey->u.ec.DEREncodedParams; |
| 824 » } | 826 } |
| 825 | 827 |
| 826 » /* perform client side ops */ | 828 /* perform client side ops */ |
| 827 » /* generate a pair of ephemeral keys using server's parms */ | 829 /* generate a pair of ephemeral keys using server's parms */ |
| 828 » cpriv = SECKEY_CreateECPrivateKey(pecParams, &cpub, NULL); | 830 cpriv = SECKEY_CreateECPrivateKey(pecParams, &cpub, NULL); |
| 829 » if (!cpriv || !cpub) { | 831 if (!cpriv || !cpub) { |
| 830 » » if (testecdhe) { | 832 if (testecdhe) { |
| 831 » » SECKEY_DestroyPrivateKey(keapriv); | 833 SECKEY_DestroyPrivateKey(keapriv); |
| 832 » » SECKEY_DestroyPublicKey(keapub); | 834 SECKEY_DestroyPublicKey(keapub); |
| 833 » » } | 835 } |
| 834 » » PORT_SetError(SEC_ERROR_KEYGEN_FAIL); | 836 PORT_SetError(SEC_ERROR_KEYGEN_FAIL); |
| 835 » » rv = SECFailure; | 837 rv = SECFailure; |
| 836 » » break; | 838 break; |
| 837 » } | 839 } |
| 838 » /* now do the server side */ | 840 /* now do the server side */ |
| 839 » /* determine the PMS using client's public value */ | 841 /* determine the PMS using client's public value */ |
| 840 » target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE_DH | 842 target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE_DH |
| 841 » » » : CKM_SSL3_MASTER_KEY_DERIVE_DH; | 843 : CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 842 » pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, | 844 pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, |
| 843 » » » » CKM_ECDH1_DERIVE, | 845 CKM_ECDH1_DERIVE, |
| 844 » » » » target, | 846 target, |
| 845 » » » » CKA_DERIVE, 0, CKD_NULL, NULL, NULL); | 847 CKA_DERIVE, 0, CKD_NULL, NULL, NULL); |
| 846 » rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); | 848 rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); |
| 847 » SECKEY_DestroyPrivateKey(cpriv); | 849 SECKEY_DestroyPrivateKey(cpriv); |
| 848 » SECKEY_DestroyPublicKey(cpub); | 850 SECKEY_DestroyPublicKey(cpub); |
| 849 » if (testecdhe) { | 851 if (testecdhe) { |
| 850 » » SECKEY_DestroyPrivateKey(keapriv); | 852 SECKEY_DestroyPrivateKey(keapriv); |
| 851 » » SECKEY_DestroyPublicKey(keapub); | 853 SECKEY_DestroyPublicKey(keapub); |
| 852 » } | 854 } |
| 853 » if (rv == SECSuccess && *pcanbypass == PR_FALSE) | 855 if (rv == SECSuccess && *pcanbypass == PR_FALSE) |
| 854 » » goto done; | 856 goto done; |
| 855 » break; | 857 break; |
| 856 » } | 858 } |
| 857 » /* Check for NULL to avoid double free. */ | 859 /* Check for NULL to avoid double free. */ |
| 858 » if (ecParams.data != NULL) { | 860 if (ecParams.data != NULL) { |
| 859 » PORT_Free(ecParams.data); | 861 PORT_Free(ecParams.data); |
| 860 » ecParams.data = NULL; | 862 ecParams.data = NULL; |
| 861 » } | 863 } |
| 862 #endif /* NSS_DISABLE_ECC */ | 864 #endif /* NSS_DISABLE_ECC */ |
| 863 » if (pms) | 865 if (pms) |
| 864 » PK11_FreeSymKey(pms); | 866 PK11_FreeSymKey(pms); |
| 865 } | 867 } |
| 866 | 868 |
| 867 /* *pcanbypass has been set */ | 869 /* *pcanbypass has been set */ |
| 868 rv = SECSuccess; | 870 rv = SECSuccess; |
| 869 | 871 |
| 870 done: | 872 done: |
| 871 if (pms) | 873 if (pms) |
| 872 » PK11_FreeSymKey(pms); | 874 PK11_FreeSymKey(pms); |
| 873 | 875 |
| 874 /* Check for NULL to avoid double free. | 876 /* Check for NULL to avoid double free. |
| 875 * SECItem_FreeItem sets data NULL in secitem.c#265 | 877 * SECItem_FreeItem sets data NULL in secitem.c#265 |
| 876 */ | 878 */ |
| 877 if (enc_pms.data != NULL) { | 879 if (enc_pms.data != NULL) { |
| 878 » SECITEM_FreeItem(&enc_pms, PR_FALSE); | 880 SECITEM_FreeItem(&enc_pms, PR_FALSE); |
| 879 } | 881 } |
| 880 #ifndef NSS_DISABLE_ECC | 882 #ifndef NSS_DISABLE_ECC |
| 881 if (ecParams.data != NULL) { | 883 if (ecParams.data != NULL) { |
| 882 PORT_Free(ecParams.data); | 884 PORT_Free(ecParams.data); |
| 883 ecParams.data = NULL; | 885 ecParams.data = NULL; |
| 884 } | 886 } |
| 885 #endif /* NSS_DISABLE_ECC */ | 887 #endif /* NSS_DISABLE_ECC */ |
| 886 | 888 |
| 887 if (srvPubkey) { | 889 if (srvPubkey) { |
| 888 » SECKEY_DestroyPublicKey(srvPubkey); | 890 SECKEY_DestroyPublicKey(srvPubkey); |
| 889 » srvPubkey = NULL; | 891 srvPubkey = NULL; |
| 890 } | 892 } |
| 891 | 893 |
| 892 | |
| 893 return rv; | 894 return rv; |
| 894 #endif /* NO_PKCS11_BYPASS */ | 895 #endif /* NO_PKCS11_BYPASS */ |
| 895 } | 896 } |
| 896 | |
| OLD | NEW |