OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/crypto/p256_key_exchange.h" | 5 #include "net/quic/crypto/p256_key_exchange.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/sys_byteorder.h" | 8 #include "base/sys_byteorder.h" |
9 | 9 |
10 using base::StringPiece; | 10 using base::StringPiece; |
(...skipping 23 matching lines...) Expand all Loading... |
34 memcpy(public_key_, public_key, sizeof(public_key_)); | 34 memcpy(public_key_, public_key, sizeof(public_key_)); |
35 } | 35 } |
36 | 36 |
37 P256KeyExchange::~P256KeyExchange() { | 37 P256KeyExchange::~P256KeyExchange() { |
38 } | 38 } |
39 | 39 |
40 // static | 40 // static |
41 P256KeyExchange* P256KeyExchange::New(StringPiece key) { | 41 P256KeyExchange* P256KeyExchange::New(StringPiece key) { |
42 if (key.size() < 2) { | 42 if (key.size() < 2) { |
43 DVLOG(1) << "Key pair is too small."; | 43 DVLOG(1) << "Key pair is too small."; |
44 return NULL; | 44 return nullptr; |
45 } | 45 } |
46 | 46 |
47 const uint8* data = reinterpret_cast<const uint8*>(key.data()); | 47 const uint8* data = reinterpret_cast<const uint8*>(key.data()); |
48 size_t size = static_cast<size_t>(data[0]) | | 48 size_t size = static_cast<size_t>(data[0]) | |
49 (static_cast<size_t>(data[1]) << 8); | 49 (static_cast<size_t>(data[1]) << 8); |
50 key.remove_prefix(2); | 50 key.remove_prefix(2); |
51 if (key.size() < size) { | 51 if (key.size() < size) { |
52 DVLOG(1) << "Key pair does not contain key material."; | 52 DVLOG(1) << "Key pair does not contain key material."; |
53 return NULL; | 53 return nullptr; |
54 } | 54 } |
55 | 55 |
56 StringPiece private_piece(key.data(), size); | 56 StringPiece private_piece(key.data(), size); |
57 key.remove_prefix(size); | 57 key.remove_prefix(size); |
58 if (key.empty()) { | 58 if (key.empty()) { |
59 DVLOG(1) << "Key pair does not contain public key."; | 59 DVLOG(1) << "Key pair does not contain public key."; |
60 return NULL; | 60 return nullptr; |
61 } | 61 } |
62 | 62 |
63 StringPiece public_piece(key); | 63 StringPiece public_piece(key); |
64 | 64 |
65 scoped_ptr<crypto::ECPrivateKey> key_pair( | 65 scoped_ptr<crypto::ECPrivateKey> key_pair( |
66 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( | 66 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
67 kExportPassword, | 67 kExportPassword, |
68 // TODO(thaidn): fix this interface to avoid copying secrets. | 68 // TODO(thaidn): fix this interface to avoid copying secrets. |
69 StringPieceToVector(private_piece), | 69 StringPieceToVector(private_piece), |
70 StringPieceToVector(public_piece))); | 70 StringPieceToVector(public_piece))); |
71 | 71 |
72 if (!key_pair.get()) { | 72 if (!key_pair.get()) { |
73 DVLOG(1) << "Can't decrypt private key."; | 73 DVLOG(1) << "Can't decrypt private key."; |
74 return NULL; | 74 return nullptr; |
75 } | 75 } |
76 | 76 |
77 // Perform some sanity checks on the public key. | 77 // Perform some sanity checks on the public key. |
78 SECKEYPublicKey* public_key = key_pair->public_key(); | 78 SECKEYPublicKey* public_key = key_pair->public_key(); |
79 if (public_key->keyType != ecKey || | 79 if (public_key->keyType != ecKey || |
80 public_key->u.ec.publicValue.len != kUncompressedP256PointBytes || | 80 public_key->u.ec.publicValue.len != kUncompressedP256PointBytes || |
81 !public_key->u.ec.publicValue.data || | 81 !public_key->u.ec.publicValue.data || |
82 public_key->u.ec.publicValue.data[0] != kUncompressedECPointForm) { | 82 public_key->u.ec.publicValue.data[0] != kUncompressedECPointForm) { |
83 DVLOG(1) << "Key is invalid."; | 83 DVLOG(1) << "Key is invalid."; |
84 return NULL; | 84 return nullptr; |
85 } | 85 } |
86 | 86 |
87 // Ensure that the key is using the correct curve, i.e., NIST P-256. | 87 // Ensure that the key is using the correct curve, i.e., NIST P-256. |
88 const SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); | 88 const SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); |
89 if (!oid_data) { | 89 if (!oid_data) { |
90 DVLOG(1) << "Can't get P-256's OID."; | 90 DVLOG(1) << "Can't get P-256's OID."; |
91 return NULL; | 91 return nullptr; |
92 } | 92 } |
93 | 93 |
94 if (public_key->u.ec.DEREncodedParams.len != oid_data->oid.len + 2 || | 94 if (public_key->u.ec.DEREncodedParams.len != oid_data->oid.len + 2 || |
95 !public_key->u.ec.DEREncodedParams.data || | 95 !public_key->u.ec.DEREncodedParams.data || |
96 public_key->u.ec.DEREncodedParams.data[0] != SEC_ASN1_OBJECT_ID || | 96 public_key->u.ec.DEREncodedParams.data[0] != SEC_ASN1_OBJECT_ID || |
97 public_key->u.ec.DEREncodedParams.data[1] != oid_data->oid.len || | 97 public_key->u.ec.DEREncodedParams.data[1] != oid_data->oid.len || |
98 memcmp(public_key->u.ec.DEREncodedParams.data + 2, | 98 memcmp(public_key->u.ec.DEREncodedParams.data + 2, |
99 oid_data->oid.data, oid_data->oid.len) != 0) { | 99 oid_data->oid.data, oid_data->oid.len) != 0) { |
100 DVLOG(1) << "Key is invalid."; | 100 DVLOG(1) << "Key is invalid."; |
101 } | 101 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 // As this function is used for SSL/TLS's ECDH key exchanges it has many | 185 // As this function is used for SSL/TLS's ECDH key exchanges it has many |
186 // arguments, most of which are not required in QUIC. | 186 // arguments, most of which are not required in QUIC. |
187 // Key derivation function CKD_NULL is used because the return value of | 187 // Key derivation function CKD_NULL is used because the return value of |
188 // |CalculateSharedKey| is the actual ECDH shared key, not any derived keys | 188 // |CalculateSharedKey| is the actual ECDH shared key, not any derived keys |
189 // from it. | 189 // from it. |
190 crypto::ScopedPK11SymKey premaster_secret( | 190 crypto::ScopedPK11SymKey premaster_secret( |
191 PK11_PubDeriveWithKDF( | 191 PK11_PubDeriveWithKDF( |
192 key_pair_->key(), | 192 key_pair_->key(), |
193 &peer_public_key, | 193 &peer_public_key, |
194 PR_FALSE, | 194 PR_FALSE, |
195 NULL, | 195 nullptr, |
196 NULL, | 196 nullptr, |
197 CKM_ECDH1_DERIVE, /* mechanism */ | 197 CKM_ECDH1_DERIVE, /* mechanism */ |
198 CKM_GENERIC_SECRET_KEY_GEN, /* target */ | 198 CKM_GENERIC_SECRET_KEY_GEN, /* target */ |
199 CKA_DERIVE, | 199 CKA_DERIVE, |
200 0, | 200 0, |
201 CKD_NULL, /* kdf */ | 201 CKD_NULL, /* kdf */ |
202 NULL, | 202 nullptr, |
203 NULL)); | 203 nullptr)); |
204 | 204 |
205 if (!premaster_secret.get()) { | 205 if (!premaster_secret.get()) { |
206 DVLOG(1) << "Can't derive ECDH shared key."; | 206 DVLOG(1) << "Can't derive ECDH shared key."; |
207 return false; | 207 return false; |
208 } | 208 } |
209 | 209 |
210 if (PK11_ExtractKeyValue(premaster_secret.get()) != SECSuccess) { | 210 if (PK11_ExtractKeyValue(premaster_secret.get()) != SECSuccess) { |
211 DVLOG(1) << "Can't extract raw ECDH shared key."; | 211 DVLOG(1) << "Can't extract raw ECDH shared key."; |
212 return false; | 212 return false; |
213 } | 213 } |
214 | 214 |
215 SECItem* key_data = PK11_GetKeyData(premaster_secret.get()); | 215 SECItem* key_data = PK11_GetKeyData(premaster_secret.get()); |
216 if (!key_data || !key_data->data || key_data->len != kP256FieldBytes) { | 216 if (!key_data || !key_data->data || key_data->len != kP256FieldBytes) { |
217 DVLOG(1) << "ECDH shared key is invalid."; | 217 DVLOG(1) << "ECDH shared key is invalid."; |
218 return false; | 218 return false; |
219 } | 219 } |
220 | 220 |
221 out_result->assign(reinterpret_cast<char*>(key_data->data), key_data->len); | 221 out_result->assign(reinterpret_cast<char*>(key_data->data), key_data->len); |
222 return true; | 222 return true; |
223 } | 223 } |
224 | 224 |
225 StringPiece P256KeyExchange::public_value() const { | 225 StringPiece P256KeyExchange::public_value() const { |
226 return StringPiece(reinterpret_cast<const char*>(public_key_), | 226 return StringPiece(reinterpret_cast<const char*>(public_key_), |
227 sizeof(public_key_)); | 227 sizeof(public_key_)); |
228 } | 228 } |
229 | 229 |
230 QuicTag P256KeyExchange::tag() const { return kP256; } | 230 QuicTag P256KeyExchange::tag() const { return kP256; } |
231 | 231 |
232 } // namespace net | 232 } // namespace net |
233 | |
OLD | NEW |