OLD | NEW |
| (Empty) |
1 // Copyright 2003-2009 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 // | |
16 // signatures.h | |
17 // | |
18 // Classes and functions related to crypto-hashes of buffers and digital | |
19 // signatures of buffers. | |
20 | |
21 #ifndef OMAHA_BASE_SIGNATURES_H_ | |
22 #define OMAHA_BASE_SIGNATURES_H_ | |
23 | |
24 #include <windows.h> | |
25 #include <wincrypt.h> | |
26 #include <atlstr.h> | |
27 #include <vector> | |
28 #include "base/basictypes.h" | |
29 #include "omaha/base/scoped_any.h" | |
30 | |
31 namespace omaha { | |
32 | |
33 // Forward decls of classes defined here | |
34 class CryptoHash; | |
35 class CryptoComputeSignature; | |
36 class CryptoVerifySignature; | |
37 class CryptoSigningCertificate; | |
38 class CryptoSignatureVerificationCertificate; | |
39 | |
40 // Useful scoped pointers for working with CryptoAPI objects | |
41 namespace CryptDetails { | |
42 | |
43 void crypt_close_store(HCERTSTORE); | |
44 void crypt_release_context(HCRYPTPROV); | |
45 void crypt_free_certificate(PCCERT_CONTEXT); | |
46 void crypt_destroy_key(HCRYPTKEY); | |
47 | |
48 typedef close_fun<void (*)(HCERTSTORE),crypt_close_store> smart_close
_store; // NOLINT | |
49 typedef close_fun<void (*)(HCRYPTPROV),crypt_release_context> smart_relea
se_context; // NOLINT | |
50 typedef close_fun<void (*)(PCCERT_CONTEXT),crypt_free_certificate> smart_free_
certificate; // NOLINT | |
51 typedef close_fun<void (*)(HCRYPTKEY),crypt_destroy_key> smart_destr
oy_key; // NOLINT | |
52 | |
53 typedef scoped_any<HCERTSTORE,smart_close_store,null_t> scoped_cryp
t_store; // NOLINT | |
54 typedef scoped_any<HCRYPTPROV,smart_release_context,null_t> scoped_cryp
t_context; // NOLINT | |
55 typedef scoped_any<PCCERT_CONTEXT,smart_free_certificate,null_t> scoped_cryp
t_cert; // NOLINT | |
56 typedef scoped_any<HCRYPTKEY,smart_destroy_key,null_t> scoped_cryp
t_key; // NOLINT | |
57 } | |
58 | |
59 // A namespace for encoding binary into base64 (portable ASCII) representation | |
60 // and for decoding it again. | |
61 namespace Base64 { | |
62 // Binary -> base64 in a buffer | |
63 HRESULT Encode(const std::vector<byte>& buffer_in, | |
64 std::vector<byte>* encoded, | |
65 bool break_into_lines = true); | |
66 | |
67 // Binary -> base64 in a string | |
68 HRESULT Encode(const std::vector<byte>& buffer_in, | |
69 CStringA* encoded, | |
70 bool break_into_lines = true); | |
71 | |
72 // Binary -> base64 in a wide string | |
73 HRESULT Encode(const std::vector<byte>& buffer_in, | |
74 CString* encoded, | |
75 bool break_into_lines = true); | |
76 | |
77 // Base64 in a buffer -> binary | |
78 HRESULT Decode(const std::vector<byte>& encoded, | |
79 std::vector<byte>* buffer_out); | |
80 | |
81 // Base64 in a CStringA -> binary | |
82 HRESULT Decode(const CStringA& encoded, std::vector<byte>* buffer_out); | |
83 | |
84 // Base64 in a CString -> binary | |
85 HRESULT Decode(const CString& encoded, std::vector<byte>* buffer_out); | |
86 } | |
87 | |
88 | |
89 // Compute and validate SHA-1 hashes of data | |
90 class CryptoHash { | |
91 public: | |
92 | |
93 CryptoHash(); | |
94 ~CryptoHash(); | |
95 | |
96 static const int kHashSize = 20; | |
97 | |
98 // Hash a file | |
99 HRESULT Compute(const TCHAR * filepath, | |
100 uint64 max_len, | |
101 std::vector<byte>* hash_out); | |
102 | |
103 // Hash a list of files | |
104 HRESULT Compute(const std::vector<CString>& filepaths, | |
105 uint64 max_len, | |
106 std::vector<byte>* hash_out); | |
107 | |
108 // Hash a buffer | |
109 HRESULT Compute(const std::vector<byte>& buffer_in, | |
110 std::vector<byte>* hash_out); | |
111 | |
112 // Verify hash of a file | |
113 HRESULT Validate(const TCHAR * filepath, | |
114 uint64 max_len, | |
115 const std::vector<byte>& hash_in); | |
116 | |
117 // Verify hash of a list of files | |
118 HRESULT Validate(const std::vector<CString>& filepaths, | |
119 uint64 max_len, | |
120 const std::vector<byte>& hash_in); | |
121 | |
122 // Verify hash of a buffer | |
123 HRESULT Validate(const std::vector<byte>& buffer_in, | |
124 const std::vector<byte>& hash_in); | |
125 | |
126 private: | |
127 // Compute or verify hash of a file | |
128 HRESULT ComputeOrValidate(const std::vector<CString>& filepaths, | |
129 uint64 max_len, | |
130 const std::vector<byte>* hash_in, | |
131 std::vector<byte>* hash_out); | |
132 | |
133 // Compute or verify hash of a buffer | |
134 HRESULT ComputeOrValidate(const std::vector<byte>& buffer_in, | |
135 const std::vector<byte>* hash_in, | |
136 std::vector<byte>* hash_out); | |
137 | |
138 DISALLOW_EVIL_CONSTRUCTORS(CryptoHash); | |
139 }; | |
140 | |
141 | |
142 // Import and use a certificate for signing data (has a private key) | |
143 class CryptoSigningCertificate { | |
144 public: | |
145 CryptoSigningCertificate(); | |
146 ~CryptoSigningCertificate(); | |
147 | |
148 // Import certificate - with both public key and private key. | |
149 // Must be in PFX format. Password must unlock the PFX file. | |
150 // subject_name is the certificate's subject name (who it was | |
151 // issued to) - if not NULL then it is checked for an exact | |
152 // match against the certificate. | |
153 | |
154 // User can get the certificate in PFX format by following the procedure at | |
155 // http://support.globalsign.net/en/objectsign/transform.cfm | |
156 | |
157 HRESULT ImportCertificate(const TCHAR * filepath, | |
158 const TCHAR * password, | |
159 const TCHAR * subject_name); | |
160 | |
161 HRESULT ImportCertificate(const std::vector<byte>& certificate_in, | |
162 const TCHAR * password, | |
163 const TCHAR * subject_name); | |
164 | |
165 CString subject_name() { return subject_name_; } | |
166 | |
167 private: | |
168 static const int kMaxCertificateSize = 100000; | |
169 | |
170 CryptDetails::scoped_crypt_store store_; | |
171 CryptDetails::scoped_crypt_cert certificate_; | |
172 CryptDetails::scoped_crypt_context csp_; | |
173 CString subject_name_; | |
174 DWORD key_spec_; | |
175 | |
176 friend class CryptoComputeSignature; | |
177 // Get the CSP with the private key | |
178 // (CryptoSigningCertificate retains ownership of csp_context.) | |
179 HRESULT GetCSPContext(HCRYPTPROV* csp_context); | |
180 | |
181 DISALLOW_EVIL_CONSTRUCTORS(CryptoSigningCertificate); | |
182 }; | |
183 | |
184 | |
185 // Compute digital signatures | |
186 class CryptoComputeSignature { | |
187 public: | |
188 explicit CryptoComputeSignature(CryptoSigningCertificate* certificate); | |
189 ~CryptoComputeSignature(); | |
190 | |
191 // Sign a file, returning a separate signature | |
192 HRESULT Sign(const TCHAR * filepath, | |
193 uint32 max_len, | |
194 std::vector<byte>* signature_out); | |
195 | |
196 // Sign a chunk of memory, returning a separate signature | |
197 HRESULT Sign(const std::vector<byte>& buffer_in, | |
198 std::vector<byte>* signature_out); | |
199 | |
200 private: | |
201 // Does not take ownership of the certificate | |
202 CryptoSigningCertificate* const certificate_; | |
203 | |
204 DISALLOW_EVIL_CONSTRUCTORS(CryptoComputeSignature); | |
205 }; | |
206 | |
207 | |
208 // Import and use a certificate for verifying signatures (has public key only) | |
209 class CryptoSignatureVerificationCertificate { | |
210 public: | |
211 CryptoSignatureVerificationCertificate(); | |
212 ~CryptoSignatureVerificationCertificate(); | |
213 | |
214 // Import certificate - with only public key. Must be in DER (.cer) format. | |
215 // subject_name is the certificate's subject name (who it was | |
216 // issued to) - if not NULL then it is checked for an exact | |
217 // match against the certificate. | |
218 | |
219 // User can get certificate in DER format (.cer) by exporting from | |
220 // certmgr.exe, using openssl, etc.) | |
221 | |
222 HRESULT ImportCertificate(const TCHAR * filepath, | |
223 const TCHAR * subject_name); | |
224 HRESULT ImportCertificate(const std::vector<byte>& certificate_in, | |
225 const TCHAR * subject_name); | |
226 | |
227 CString subject_name() { return subject_name_; } | |
228 | |
229 private: | |
230 static const int kMaxCertificateSize = 100000; | |
231 | |
232 CryptDetails::scoped_crypt_cert certificate_; | |
233 CryptDetails::scoped_crypt_context csp_; | |
234 CryptDetails::scoped_crypt_key key_; | |
235 CString subject_name_; | |
236 | |
237 friend class CryptoVerifySignature; | |
238 // Get the CSP and the public key | |
239 // (CryptoSignatureVerificationCertificate retains ownership of csp_context | |
240 // and public_key.) | |
241 HRESULT GetCSPContextAndKey(HCRYPTPROV* csp_context, HCRYPTKEY* public_key); | |
242 | |
243 DISALLOW_EVIL_CONSTRUCTORS(CryptoSignatureVerificationCertificate); | |
244 }; | |
245 | |
246 | |
247 // Verify digital signatures | |
248 class CryptoVerifySignature { | |
249 public: | |
250 explicit CryptoVerifySignature( | |
251 CryptoSignatureVerificationCertificate& certificate); | |
252 ~CryptoVerifySignature(); | |
253 | |
254 // Validate signature of a file, signature given separately | |
255 HRESULT Validate(const TCHAR * filepath, | |
256 uint32 max_len, | |
257 const std::vector<byte>& signature_in); | |
258 | |
259 // Validate signature of a buffer of data, signature given separately | |
260 HRESULT Validate(const std::vector<byte>& buffer_in, | |
261 const std::vector<byte>& signature_in); | |
262 | |
263 private: | |
264 // Does not take ownership of the certificate | |
265 CryptoSignatureVerificationCertificate* const certificate_; | |
266 | |
267 DISALLOW_EVIL_CONSTRUCTORS(CryptoVerifySignature); | |
268 }; | |
269 | |
270 | |
271 // All-in-one routine to sign a chunk of data and return the signature | |
272 // (encoded in base64) | |
273 HRESULT SignData(const TCHAR* certificate_path, | |
274 const TCHAR* certificate_password, | |
275 const TCHAR* certificate_subject_name, | |
276 const std::vector<byte>& data, | |
277 CString* signature_base64); | |
278 | |
279 // All-in-one routine to verify the signature of a chunk of data | |
280 HRESULT VerifyData(const TCHAR* certificate_path, | |
281 const TCHAR* certificate_subject_name, | |
282 const std::vector<byte>& data, | |
283 const TCHAR* signature_base64); | |
284 | |
285 HRESULT VerifyData(const std::vector<byte>& certificate_buffer, | |
286 const TCHAR* certificate_subject_name, | |
287 const std::vector<byte>& data, | |
288 const TCHAR* signature_base64); | |
289 | |
290 // Authenticate files | |
291 HRESULT AuthenticateFiles(const std::vector<CString>& files, | |
292 const CString& hash); | |
293 | |
294 } // namespace omaha | |
295 | |
296 #endif // OMAHA_BASE_SIGNATURES_H_ | |
OLD | NEW |