OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/quic/crypto/channel_id.h" | |
6 | |
7 #include <keythi.h> | |
8 #include <pk11pub.h> | |
9 #include <sechash.h> | |
10 | |
11 using base::StringPiece; | |
12 | |
13 namespace net { | |
14 | |
15 // static | |
16 bool ChannelIDVerifier::Verify(StringPiece key, | |
17 StringPiece signed_data, | |
18 StringPiece signature) { | |
19 return VerifyRaw(key, signed_data, signature, true); | |
20 } | |
21 | |
22 // static | |
23 bool ChannelIDVerifier::VerifyRaw(StringPiece key, | |
24 StringPiece signed_data, | |
25 StringPiece signature, | |
26 bool is_channel_id_signature) { | |
27 if (key.size() != 32 * 2 || signature.size() != 32 * 2) { | |
28 return false; | |
29 } | |
30 | |
31 SECKEYPublicKey public_key; | |
32 memset(&public_key, 0, sizeof(public_key)); | |
33 | |
34 // DER encoding of the object identifier (OID) of the named curve P-256 | |
35 // (1.2.840.10045.3.1.7). See RFC 6637 Section 11. | |
36 static const unsigned char p256_oid[] = {0x06, 0x08, 0x2a, 0x86, 0x48, | |
37 0xce, 0x3d, 0x03, 0x01, 0x07}; | |
38 public_key.keyType = ecKey; | |
39 public_key.u.ec.DEREncodedParams.type = siBuffer; | |
40 public_key.u.ec.DEREncodedParams.data = const_cast<unsigned char*>(p256_oid); | |
41 public_key.u.ec.DEREncodedParams.len = sizeof(p256_oid); | |
42 | |
43 unsigned char key_buf[65]; | |
44 key_buf[0] = 0x04; | |
45 memcpy(&key_buf[1], key.data(), key.size()); | |
46 public_key.u.ec.publicValue.type = siBuffer; | |
47 public_key.u.ec.publicValue.data = key_buf; | |
48 public_key.u.ec.publicValue.len = sizeof(key_buf); | |
49 | |
50 SECItem signature_item = {siBuffer, reinterpret_cast<unsigned char*>( | |
51 const_cast<char*>(signature.data())), | |
52 static_cast<unsigned int>(signature.size())}; | |
53 | |
54 unsigned char hash_buf[SHA256_LENGTH]; | |
55 SECItem hash_item = {siBuffer, hash_buf, sizeof(hash_buf)}; | |
56 | |
57 HASHContext* sha256 = HASH_Create(HASH_AlgSHA256); | |
58 if (!sha256) { | |
59 return false; | |
60 } | |
61 HASH_Begin(sha256); | |
62 if (is_channel_id_signature) { | |
63 HASH_Update(sha256, reinterpret_cast<const unsigned char*>(kContextStr), | |
64 strlen(kContextStr) + 1); | |
65 HASH_Update(sha256, | |
66 reinterpret_cast<const unsigned char*>(kClientToServerStr), | |
67 strlen(kClientToServerStr) + 1); | |
68 } | |
69 HASH_Update(sha256, | |
70 reinterpret_cast<const unsigned char*>(signed_data.data()), | |
71 signed_data.size()); | |
72 HASH_End(sha256, hash_buf, &hash_item.len, sizeof(hash_buf)); | |
73 HASH_Destroy(sha256); | |
74 | |
75 return PK11_Verify(&public_key, &signature_item, &hash_item, nullptr) == | |
76 SECSuccess; | |
77 } | |
78 | |
79 } // namespace net | |
OLD | NEW |