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