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/crypto/channel_id.h" | 5 #include "net/quic/crypto/channel_id.h" |
6 | 6 |
7 #include <keythi.h> | |
8 #include <pk11pub.h> | |
9 #include <sechash.h> | |
10 | |
11 #include "base/logging.h" | |
12 | |
7 using base::StringPiece; | 13 using base::StringPiece; |
14 using std::string; | |
8 | 15 |
9 namespace net { | 16 namespace net { |
10 | 17 |
11 // TODO(rtenneti): Implement NSS support for ChannelIDVerifier::Verify and | |
12 // real ChannelIDSigner (using the SpdyCredentialBuilder as a model). | |
13 // static | 18 // static |
14 bool ChannelIDVerifier::Verify(StringPiece key, | 19 bool ChannelIDVerifier::Verify(StringPiece key, |
15 StringPiece signed_data, | 20 StringPiece signed_data, |
16 StringPiece signature) { | 21 StringPiece signature) { |
17 return true; | 22 return VerifyRaw(key, signed_data, signature, true); |
23 } | |
24 | |
25 // static | |
26 bool ChannelIDVerifier::VerifyRaw(StringPiece key, | |
27 StringPiece signed_data, | |
28 StringPiece signature, | |
29 bool is_channel_id_signature) { | |
30 if (key.size() != 32 * 2 || | |
31 signature.size() != 32 * 2) { | |
32 return false; | |
33 } | |
34 | |
35 SECKEYPublicKey public_key; | |
36 memset(&public_key, 0, sizeof(public_key)); | |
37 | |
38 // The object identifier (OID) of the named curve P-256. | |
39 static const unsigned char p256_oid[] = { | |
40 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 | |
41 }; | |
42 public_key.keyType = ecKey; | |
43 public_key.u.ec.DEREncodedParams.type = siBuffer; | |
44 public_key.u.ec.DEREncodedParams.data = const_cast<unsigned char*>(p256_oid); | |
45 public_key.u.ec.DEREncodedParams.len = sizeof(p256_oid); | |
46 | |
47 unsigned char key_buf[65]; | |
48 key_buf[0] = 0x04; | |
49 memcpy(&key_buf[1], key.data(), key.size()); | |
50 public_key.u.ec.publicValue.type = siBuffer; | |
51 public_key.u.ec.publicValue.data = key_buf; | |
52 public_key.u.ec.publicValue.len = sizeof(key_buf); | |
53 | |
54 SECItem signature_item = { | |
55 siBuffer, | |
56 reinterpret_cast<unsigned char*>(const_cast<char*>(signature.data())), | |
57 signature.size() | |
58 }; | |
59 | |
60 unsigned char hash_buf[SHA256_LENGTH]; | |
61 SECItem hash_item = { siBuffer, hash_buf, sizeof(hash_buf) }; | |
62 | |
63 HASHContext* sha256 = HASH_Create(HASH_AlgSHA256); | |
64 if (!sha256) { | |
65 return false; | |
66 } | |
67 HASH_Begin(sha256); | |
68 if (is_channel_id_signature) { | |
69 HASH_Update(sha256, reinterpret_cast<const unsigned char*>(kContextStr), | |
70 strlen(kContextStr) + 1); | |
71 HASH_Update(sha256, | |
72 reinterpret_cast<const unsigned char*>(kClientToServerStr), | |
73 strlen(kClientToServerStr) + 1); | |
74 } | |
75 HASH_Update(sha256, | |
76 reinterpret_cast<const unsigned char*>(signed_data.data()), | |
77 signed_data.size()); | |
78 HASH_End(sha256, hash_buf, &hash_item.len, sizeof(hash_buf)); | |
79 HASH_Destroy(sha256); | |
80 | |
81 SECStatus rv = PK11_Verify(&public_key, &signature_item, &hash_item, NULL); | |
agl
2013/06/12 15:29:57
nit: seems that these two lines could be merged al
wtc
2013/06/12 18:11:01
Done.
| |
82 return rv == SECSuccess; | |
18 } | 83 } |
19 | 84 |
20 } // namespace net | 85 } // namespace net |
OLD | NEW |