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
3 // found in the LICENSE file.
5 #include "net/quic/test_tools/crypto_test_utils.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h"
13 #include "crypto/ec_private_key.h"
14 #include "net/quic/crypto/channel_id.h"
16 using base::StringPiece;
23 // TODO(rtenneti): Implement NSS support ChannelIDSigner. Convert Sign() to be
24 // asynchronous using completion callback. After porting TestChannelIDSigner,
25 // implement real ChannelIDSigner.
26 class TestChannelIDSigner : public ChannelIDSigner {
28 virtual ~TestChannelIDSigner() {
29 STLDeleteValues(&hostname_to_key_);
32 // ChannelIDSigner implementation.
34 virtual bool Sign(const string& hostname,
35 StringPiece signed_data,
37 string* out_signature) OVERRIDE {
38 crypto::ECPrivateKey* ecdsa_keypair = HostnameToKey(hostname);
43 *out_key = SerializeKey(ecdsa_keypair->public_key());
44 if (out_key->empty()) {
48 unsigned char hash_buf[SHA256_LENGTH];
49 SECItem hash_item = { siBuffer, hash_buf, sizeof(hash_buf) };
51 HASHContext* sha256 = HASH_Create(HASH_AlgSHA256);
57 reinterpret_cast<const unsigned char*>(
58 ChannelIDVerifier::kContextStr),
59 strlen(ChannelIDVerifier::kContextStr) + 1);
61 reinterpret_cast<const unsigned char*>(
62 ChannelIDVerifier::kClientToServerStr),
63 strlen(ChannelIDVerifier::kClientToServerStr) + 1);
65 reinterpret_cast<const unsigned char*>(signed_data.data()),
67 HASH_End(sha256, hash_buf, &hash_item.len, sizeof(hash_buf));
70 // The signature consists of a pair of 32-byte numbers.
71 static const unsigned int kSignatureLength = 32 * 2;
75 reinterpret_cast<unsigned char*>(
76 WriteInto(&signature, kSignatureLength + 1)),
80 if (PK11_Sign(ecdsa_keypair->key(), &sig_item, &hash_item) != SECSuccess) {
83 *out_signature = signature;
87 virtual string GetKeyForHostname(const string& hostname) OVERRIDE {
88 crypto::ECPrivateKey* ecdsa_keypair = HostnameToKey(hostname);
92 return SerializeKey(ecdsa_keypair->public_key());
96 typedef std::map<string, crypto::ECPrivateKey*> HostnameToKeyMap;
98 crypto::ECPrivateKey* HostnameToKey(const string& hostname) {
99 HostnameToKeyMap::const_iterator it = hostname_to_key_.find(hostname);
100 if (it != hostname_to_key_.end()) {
104 crypto::ECPrivateKey* keypair = crypto::ECPrivateKey::Create();
108 hostname_to_key_[hostname] = keypair;
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;
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) {
124 string key(reinterpret_cast<const char*>(data + 1), kExpectedKeyLength - 1);
128 HostnameToKeyMap hostname_to_key_;
132 ChannelIDSigner* CryptoTestUtils::ChannelIDSignerForTesting() {
133 return new TestChannelIDSigner();