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