OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/test_tools/crypto_test_utils.h" | 5 #include "net/quic/test_tools/crypto_test_utils.h" |
6 | 6 |
7 #include <keyhi.h> | |
8 #include <pk11pub.h> | |
9 #include <sechash.h> | |
10 | |
11 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
12 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
13 #include "crypto/ec_private_key.h" | 9 #include "crypto/ec_private_key.h" |
| 10 #include "crypto/ec_signature_creator.h" |
14 #include "net/quic/crypto/channel_id.h" | 11 #include "net/quic/crypto/channel_id.h" |
| 12 #include "net/quic/crypto/channel_id_chromium.h" |
15 | 13 |
16 using base::StringPiece; | 14 using base::StringPiece; |
17 using std::string; | 15 using std::string; |
18 | 16 |
19 namespace net { | 17 namespace net { |
20 | 18 |
21 namespace test { | 19 namespace test { |
22 | 20 |
23 // TODO(rtenneti): Convert Sign() to be asynchronous using a completion | |
24 // callback. | |
25 class TestChannelIDKey : public ChannelIDKey { | |
26 public: | |
27 explicit TestChannelIDKey(crypto::ECPrivateKey* ecdsa_keypair) | |
28 : ecdsa_keypair_(ecdsa_keypair) {} | |
29 virtual ~TestChannelIDKey() {} | |
30 | |
31 // ChannelIDKey implementation. | |
32 | |
33 virtual bool Sign(StringPiece signed_data, | |
34 string* out_signature) const OVERRIDE { | |
35 unsigned char hash_buf[SHA256_LENGTH]; | |
36 SECItem hash_item = { siBuffer, hash_buf, sizeof(hash_buf) }; | |
37 | |
38 HASHContext* sha256 = HASH_Create(HASH_AlgSHA256); | |
39 if (!sha256) { | |
40 return false; | |
41 } | |
42 HASH_Begin(sha256); | |
43 HASH_Update(sha256, | |
44 reinterpret_cast<const unsigned char*>( | |
45 ChannelIDVerifier::kContextStr), | |
46 strlen(ChannelIDVerifier::kContextStr) + 1); | |
47 HASH_Update(sha256, | |
48 reinterpret_cast<const unsigned char*>( | |
49 ChannelIDVerifier::kClientToServerStr), | |
50 strlen(ChannelIDVerifier::kClientToServerStr) + 1); | |
51 HASH_Update(sha256, | |
52 reinterpret_cast<const unsigned char*>(signed_data.data()), | |
53 signed_data.size()); | |
54 HASH_End(sha256, hash_buf, &hash_item.len, sizeof(hash_buf)); | |
55 HASH_Destroy(sha256); | |
56 | |
57 // The signature consists of a pair of 32-byte numbers. | |
58 static const unsigned int kSignatureLength = 32 * 2; | |
59 string signature; | |
60 SECItem sig_item = { | |
61 siBuffer, | |
62 reinterpret_cast<unsigned char*>( | |
63 WriteInto(&signature, kSignatureLength + 1)), | |
64 kSignatureLength | |
65 }; | |
66 | |
67 if (PK11_Sign(ecdsa_keypair_->key(), &sig_item, &hash_item) != SECSuccess) { | |
68 return false; | |
69 } | |
70 *out_signature = signature; | |
71 return true; | |
72 } | |
73 | |
74 virtual string SerializeKey() const OVERRIDE { | |
75 const SECKEYPublicKey* public_key = ecdsa_keypair_->public_key(); | |
76 | |
77 // public_key->u.ec.publicValue is an ANSI X9.62 public key which, for | |
78 // a P-256 key, is 0x04 (meaning uncompressed) followed by the x and y field | |
79 // elements as 32-byte, big-endian numbers. | |
80 static const unsigned int kExpectedKeyLength = 65; | |
81 | |
82 const unsigned char* const data = public_key->u.ec.publicValue.data; | |
83 const unsigned int len = public_key->u.ec.publicValue.len; | |
84 if (len != kExpectedKeyLength || data[0] != 0x04) { | |
85 return ""; | |
86 } | |
87 | |
88 string key(reinterpret_cast<const char*>(data + 1), kExpectedKeyLength - 1); | |
89 return key; | |
90 } | |
91 | |
92 private: | |
93 crypto::ECPrivateKey* ecdsa_keypair_; | |
94 }; | |
95 | |
96 class TestChannelIDSource : public ChannelIDSource { | 21 class TestChannelIDSource : public ChannelIDSource { |
97 public: | 22 public: |
98 virtual ~TestChannelIDSource() { | 23 virtual ~TestChannelIDSource() { |
99 STLDeleteValues(&hostname_to_key_); | 24 STLDeleteValues(&hostname_to_key_); |
100 } | 25 } |
101 | 26 |
102 // ChannelIDSource implementation. | 27 // ChannelIDSource implementation. |
103 | 28 |
104 virtual QuicAsyncStatus GetChannelIDKey( | 29 virtual QuicAsyncStatus GetChannelIDKey( |
105 const string& hostname, | 30 const string& hostname, |
106 scoped_ptr<ChannelIDKey>* channel_id_key, | 31 scoped_ptr<ChannelIDKey>* channel_id_key, |
107 ChannelIDSourceCallback* /*callback*/) OVERRIDE { | 32 ChannelIDSourceCallback* /*callback*/) OVERRIDE { |
108 channel_id_key->reset(new TestChannelIDKey(HostnameToKey(hostname))); | 33 channel_id_key->reset(new ChannelIDKeyChromium(HostnameToKey(hostname))); |
109 return QUIC_SUCCESS; | 34 return QUIC_SUCCESS; |
110 } | 35 } |
111 | 36 |
112 private: | 37 private: |
113 typedef std::map<string, crypto::ECPrivateKey*> HostnameToKeyMap; | 38 typedef std::map<string, crypto::ECPrivateKey*> HostnameToKeyMap; |
114 | 39 |
115 crypto::ECPrivateKey* HostnameToKey(const string& hostname) { | 40 crypto::ECPrivateKey* HostnameToKey(const string& hostname) { |
116 HostnameToKeyMap::const_iterator it = hostname_to_key_.find(hostname); | 41 HostnameToKeyMap::const_iterator it = hostname_to_key_.find(hostname); |
117 if (it != hostname_to_key_.end()) { | 42 if (it != hostname_to_key_.end()) { |
118 return it->second; | 43 return it->second->Copy(); |
119 } | 44 } |
120 | 45 |
121 crypto::ECPrivateKey* keypair = crypto::ECPrivateKey::Create(); | 46 crypto::ECPrivateKey* keypair = crypto::ECPrivateKey::Create(); |
122 if (!keypair) { | 47 if (!keypair) { |
123 return NULL; | 48 return NULL; |
124 } | 49 } |
125 hostname_to_key_[hostname] = keypair; | 50 hostname_to_key_[hostname] = keypair; |
126 return keypair; | 51 return keypair->Copy(); |
127 } | 52 } |
128 | 53 |
129 HostnameToKeyMap hostname_to_key_; | 54 HostnameToKeyMap hostname_to_key_; |
130 }; | 55 }; |
131 | 56 |
132 // static | 57 // static |
133 ChannelIDSource* CryptoTestUtils::ChannelIDSourceForTesting() { | 58 ChannelIDSource* CryptoTestUtils::ChannelIDSourceForTesting() { |
134 return new TestChannelIDSource(); | 59 return new TestChannelIDSource(); |
135 } | 60 } |
136 | 61 |
137 } // namespace test | 62 } // namespace test |
138 | 63 |
139 } // namespace net | 64 } // namespace net |
OLD | NEW |