| 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 |