OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/crypto/signature_verifier.h" | 5 #include "base/crypto/signature_verifier.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 | 8 |
9 #pragma comment(lib, "crypt32.lib") | 9 #pragma comment(lib, "crypt32.lib") |
10 | 10 |
11 namespace { | 11 namespace { |
12 | 12 |
13 // Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the | 13 // Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the |
14 // WINAPI calling convention. | 14 // WINAPI calling convention. |
15 void* WINAPI MyCryptAlloc(size_t size) { | 15 void* WINAPI MyCryptAlloc(size_t size) { |
16 return malloc(size); | 16 return malloc(size); |
17 } | 17 } |
18 | 18 |
19 void WINAPI MyCryptFree(void* p) { | 19 void WINAPI MyCryptFree(void* p) { |
20 free(p); | 20 free(p); |
21 } | 21 } |
22 | 22 |
23 } // namespace | 23 } // namespace |
24 | 24 |
25 namespace base { | 25 namespace base { |
26 | 26 |
27 SignatureVerifier::SignatureVerifier() : hash_object_(0), public_key_(0) { | 27 SignatureVerifier::SignatureVerifier() : hash_object_(0), public_key_(0) { |
28 if (!CryptAcquireContext(&provider_, NULL, NULL, | 28 if (!CryptAcquireContext(provider_.receive(), NULL, NULL, |
29 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) | 29 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) |
30 provider_ = 0; | 30 provider_.reset(); |
31 } | 31 } |
32 | 32 |
33 SignatureVerifier::~SignatureVerifier() { | 33 SignatureVerifier::~SignatureVerifier() { |
34 Reset(); | 34 Reset(); |
35 if (provider_) { | |
36 BOOL ok = CryptReleaseContext(provider_, 0); | |
37 DCHECK(ok); | |
38 } | |
39 } | 35 } |
40 | 36 |
41 bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, | 37 bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, |
42 int signature_algorithm_len, | 38 int signature_algorithm_len, |
43 const uint8* signature, | 39 const uint8* signature, |
44 int signature_len, | 40 int signature_len, |
45 const uint8* public_key_info, | 41 const uint8* public_key_info, |
46 int public_key_info_len) { | 42 int public_key_info_len) { |
47 signature_.reserve(signature_len); | 43 signature_.reserve(signature_len); |
48 // CryptoAPI uses big integers in the little-endian byte order, so we need | 44 // CryptoAPI uses big integers in the little-endian byte order, so we need |
(...skipping 14 matching lines...) Expand all Loading... |
63 public_key_info_len, | 59 public_key_info_len, |
64 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, | 60 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, |
65 &decode_para, | 61 &decode_para, |
66 &cert_public_key_info, | 62 &cert_public_key_info, |
67 &struct_len); | 63 &struct_len); |
68 if (!ok) | 64 if (!ok) |
69 return false; | 65 return false; |
70 | 66 |
71 ok = CryptImportPublicKeyInfo(provider_, | 67 ok = CryptImportPublicKeyInfo(provider_, |
72 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, | 68 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, |
73 cert_public_key_info, &public_key_); | 69 cert_public_key_info, public_key_.receive()); |
74 free(cert_public_key_info); | 70 free(cert_public_key_info); |
75 if (!ok) | 71 if (!ok) |
76 return false; | 72 return false; |
77 | 73 |
78 CRYPT_ALGORITHM_IDENTIFIER* signature_algorithm_id; | 74 CRYPT_ALGORITHM_IDENTIFIER* signature_algorithm_id; |
79 struct_len = 0; | 75 struct_len = 0; |
80 ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, | 76 ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, |
81 X509_ALGORITHM_IDENTIFIER, | 77 X509_ALGORITHM_IDENTIFIER, |
82 signature_algorithm, | 78 signature_algorithm, |
83 signature_algorithm_len, | 79 signature_algorithm_len, |
(...skipping 17 matching lines...) Expand all Loading... |
101 } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { | 97 } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { |
102 // TODO(wtc): X509_ALGORITHM_IDENTIFIER isn't supported on XP SP2. We | 98 // TODO(wtc): X509_ALGORITHM_IDENTIFIER isn't supported on XP SP2. We |
103 // may be able to encapsulate signature_algorithm in a dummy SignedContent | 99 // may be able to encapsulate signature_algorithm in a dummy SignedContent |
104 // and decode it with X509_CERT into a CERT_SIGNED_CONTENT_INFO. For now, | 100 // and decode it with X509_CERT into a CERT_SIGNED_CONTENT_INFO. For now, |
105 // just hardcode the hash algorithm to be SHA-1. | 101 // just hardcode the hash algorithm to be SHA-1. |
106 hash_alg_id = CALG_SHA1; | 102 hash_alg_id = CALG_SHA1; |
107 } else { | 103 } else { |
108 return false; | 104 return false; |
109 } | 105 } |
110 | 106 |
111 ok = CryptCreateHash(provider_, hash_alg_id, 0, 0, &hash_object_); | 107 ok = CryptCreateHash(provider_, hash_alg_id, 0, 0, hash_object_.receive()); |
112 if (!ok) | 108 if (!ok) |
113 return false; | 109 return false; |
114 return true; | 110 return true; |
115 } | 111 } |
116 | 112 |
117 void SignatureVerifier::VerifyUpdate(const uint8* data_part, | 113 void SignatureVerifier::VerifyUpdate(const uint8* data_part, |
118 int data_part_len) { | 114 int data_part_len) { |
119 BOOL ok = CryptHashData(hash_object_, data_part, data_part_len, 0); | 115 BOOL ok = CryptHashData(hash_object_, data_part, data_part_len, 0); |
120 DCHECK(ok) << "CryptHashData failed: " << GetLastError(); | 116 DCHECK(ok) << "CryptHashData failed: " << GetLastError(); |
121 } | 117 } |
122 | 118 |
123 bool SignatureVerifier::VerifyFinal() { | 119 bool SignatureVerifier::VerifyFinal() { |
124 BOOL ok = CryptVerifySignature(hash_object_, &signature_[0], | 120 BOOL ok = CryptVerifySignature(hash_object_, &signature_[0], |
125 signature_.size(), public_key_, NULL, 0); | 121 signature_.size(), public_key_, NULL, 0); |
126 Reset(); | 122 Reset(); |
127 if (!ok) | 123 if (!ok) |
128 return false; | 124 return false; |
129 return true; | 125 return true; |
130 } | 126 } |
131 | 127 |
132 void SignatureVerifier::Reset() { | 128 void SignatureVerifier::Reset() { |
133 BOOL ok; | 129 hash_object_.reset(); |
134 if (hash_object_) { | 130 public_key_.reset(); |
135 ok = CryptDestroyHash(hash_object_); | |
136 DCHECK(ok); | |
137 hash_object_ = 0; | |
138 } | |
139 if (public_key_) { | |
140 ok = CryptDestroyKey(public_key_); | |
141 DCHECK(ok); | |
142 public_key_ = 0; | |
143 } | |
144 signature_.clear(); | 131 signature_.clear(); |
145 } | 132 } |
146 | 133 |
147 } // namespace base | 134 } // namespace base |
148 | 135 |
OLD | NEW |