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 |
7 using base::StringPiece; | 11 using base::StringPiece; |
8 | 12 |
9 namespace net { | 13 namespace net { |
10 | 14 |
11 // TODO(rtenneti): Implement NSS support for ChannelIDVerifier::Verify and | |
12 // real ChannelIDSigner (using the SpdyCredentialBuilder as a model). | |
13 // static | 15 // static |
14 bool ChannelIDVerifier::Verify(StringPiece key, | 16 bool ChannelIDVerifier::Verify(StringPiece key, |
15 StringPiece signed_data, | 17 StringPiece signed_data, |
16 StringPiece signature) { | 18 StringPiece signature) { |
17 return true; | 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 || |
| 28 signature.size() != 32 * 2) { |
| 29 return false; |
| 30 } |
| 31 |
| 32 SECKEYPublicKey public_key; |
| 33 memset(&public_key, 0, sizeof(public_key)); |
| 34 |
| 35 // 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. |
| 37 static const unsigned char p256_oid[] = { |
| 38 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 |
| 39 }; |
| 40 public_key.keyType = ecKey; |
| 41 public_key.u.ec.DEREncodedParams.type = siBuffer; |
| 42 public_key.u.ec.DEREncodedParams.data = const_cast<unsigned char*>(p256_oid); |
| 43 public_key.u.ec.DEREncodedParams.len = sizeof(p256_oid); |
| 44 |
| 45 unsigned char key_buf[65]; |
| 46 key_buf[0] = 0x04; |
| 47 memcpy(&key_buf[1], key.data(), key.size()); |
| 48 public_key.u.ec.publicValue.type = siBuffer; |
| 49 public_key.u.ec.publicValue.data = key_buf; |
| 50 public_key.u.ec.publicValue.len = sizeof(key_buf); |
| 51 |
| 52 SECItem signature_item = { |
| 53 siBuffer, |
| 54 reinterpret_cast<unsigned char*>(const_cast<char*>(signature.data())), |
| 55 signature.size() |
| 56 }; |
| 57 |
| 58 unsigned char hash_buf[SHA256_LENGTH]; |
| 59 SECItem hash_item = { siBuffer, hash_buf, sizeof(hash_buf) }; |
| 60 |
| 61 HASHContext* sha256 = HASH_Create(HASH_AlgSHA256); |
| 62 if (!sha256) { |
| 63 return false; |
| 64 } |
| 65 HASH_Begin(sha256); |
| 66 if (is_channel_id_signature) { |
| 67 HASH_Update(sha256, reinterpret_cast<const unsigned char*>(kContextStr), |
| 68 strlen(kContextStr) + 1); |
| 69 HASH_Update(sha256, |
| 70 reinterpret_cast<const unsigned char*>(kClientToServerStr), |
| 71 strlen(kClientToServerStr) + 1); |
| 72 } |
| 73 HASH_Update(sha256, |
| 74 reinterpret_cast<const unsigned char*>(signed_data.data()), |
| 75 signed_data.size()); |
| 76 HASH_End(sha256, hash_buf, &hash_item.len, sizeof(hash_buf)); |
| 77 HASH_Destroy(sha256); |
| 78 |
| 79 return PK11_Verify(&public_key, &signature_item, &hash_item, NULL) == |
| 80 SECSuccess; |
18 } | 81 } |
19 | 82 |
20 } // namespace net | 83 } // namespace net |
OLD | NEW |