| OLD | NEW |
| (Empty) |
| 1 // Copyright 2002-2010 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 #ifndef OMAHA_COMMON_SIGNATUREVALIDATOR_H__ | |
| 17 #define OMAHA_COMMON_SIGNATUREVALIDATOR_H__ | |
| 18 | |
| 19 #include <windows.h> | |
| 20 #include <wincrypt.h> | |
| 21 #include <atlstr.h> | |
| 22 #pragma warning(push) | |
| 23 // C4548: expression before comma has no effect | |
| 24 #pragma warning(disable : 4548) | |
| 25 #include <vector> | |
| 26 #pragma warning(pop) | |
| 27 | |
| 28 // VerifySignature() and VerifySigneeIsGoogle() should always be used together. | |
| 29 // | |
| 30 // VerifySignature() verifies that the signature is valid and has a trusted | |
| 31 // chain. It also verifies that the signing certificate was valid at the time | |
| 32 // it was used to sign. If all are true, it returns S_OK. Even if the | |
| 33 // certificate has expired since it was used to sign, the signature is valid and | |
| 34 // VerifySignature() returns S_OK. | |
| 35 // | |
| 36 // If allow_network_check is true, VerifySignature() will | |
| 37 // also check the Certificate Revocation List (CRL). If the certificate was | |
| 38 // revoked after it was used to sign, it will return S_OK. Otherwise, it fails. | |
| 39 // At no time does VerifySignature() check whether the certificate is currently | |
| 40 // valid. | |
| 41 // | |
| 42 // VerifySigneeIsGoogle() verifies that Google signed the file. It does not | |
| 43 // check the certificate chain, CRL, or anything related to the timestamp. | |
| 44 // | |
| 45 // Some of the helper classes and methods allow the caller to check whether the | |
| 46 // certificate is valid now. The above methods do not check this. | |
| 47 | |
| 48 namespace omaha { | |
| 49 | |
| 50 // Class: CertInfo | |
| 51 // | |
| 52 // CertInfo holds all sensible details of a certificate. During verification of | |
| 53 // a signature, one CertInfo object is made for each certificate encountered in | |
| 54 // the signature. | |
| 55 class CertInfo { | |
| 56 public: | |
| 57 // certificate issuing company name e.g. "Google Inc". | |
| 58 CString issuing_company_name_; | |
| 59 | |
| 60 // a company may own multiple certificates. | |
| 61 // so this tells which dept owns this certificate. | |
| 62 CString issuing_dept_name_; | |
| 63 | |
| 64 // trust-authority (or trust-provider) name. e.g. "Verisign, Inc.". | |
| 65 CString trust_authority_name_; | |
| 66 | |
| 67 // validity period start-date | |
| 68 FILETIME not_valid_before_; | |
| 69 | |
| 70 // validity period end-date | |
| 71 FILETIME not_valid_after_; | |
| 72 | |
| 73 // CERT_CONTEXT structure, defined by Crypto API, contains all the info about | |
| 74 // the certificate. | |
| 75 const CERT_CONTEXT *cert_context_; | |
| 76 | |
| 77 explicit CertInfo(const CERT_CONTEXT* given_cert_context); | |
| 78 | |
| 79 ~CertInfo(); | |
| 80 | |
| 81 // IsValidNow() functions returns true if this certificate is valid at this | |
| 82 // moment, based on the validity period specified in the certificate. | |
| 83 bool IsValidNow() const; | |
| 84 | |
| 85 // AsString() is a utility function that's used for printing CertInfo details. | |
| 86 CString AsString() const { | |
| 87 CString cert_info_str = | |
| 88 _T("Issuing Company: \"") + issuing_company_name_ + | |
| 89 _T("\" Dept: \"") + issuing_dept_name_ + | |
| 90 _T("\" Trust Provider: \"") + trust_authority_name_ + | |
| 91 _T("\" Valid From: \"") + this->FileTimeToString(¬_valid_before_) + | |
| 92 _T("\" Valid To: \"") + this->FileTimeToString(¬_valid_after_) + | |
| 93 _T("\""); | |
| 94 return cert_info_str; | |
| 95 } | |
| 96 | |
| 97 | |
| 98 // FileTimeToString() is just a convenience function to print FILETIME. | |
| 99 static CString FileTimeToString(const FILETIME* ft); | |
| 100 | |
| 101 // Given a cerificate context, this function extracts the subject/signee | |
| 102 // company name and its dept name(orgnanizational-unit-name, as they call it). | |
| 103 // Optionally, you could also retrieve trust-authority name. | |
| 104 static bool ExtractIssuerInfo(const CERT_CONTEXT* cert_context, | |
| 105 CString* orgn_name, | |
| 106 CString* orgn_dept_name, | |
| 107 CString* trust_authority = NULL); | |
| 108 | |
| 109 private: | |
| 110 // Extracts the specified field from the certificate. Only the first value for | |
| 111 // the field is extracted if multiple values are present. Returns true if | |
| 112 // the field is extracted successfully. Returns false if an error occurred | |
| 113 // during the extraction or the field was not found. | |
| 114 static bool ExtractField(const CERT_CONTEXT* cert_context, | |
| 115 const char* field_name, | |
| 116 CString* field_value); | |
| 117 }; | |
| 118 | |
| 119 // CertList is a container for a list of certificates. It is used to hold all | |
| 120 // the certificates found in the signature of a signed file. In addition, it | |
| 121 // also provides interface to fetch certificates matching to a particular | |
| 122 // criterion. | |
| 123 // | |
| 124 // Internally, CertList contains basically a vector of CertInfo* pointers. | |
| 125 // The only reason why CertList is created as opposed to simply putting all | |
| 126 // the certificates in a vector<CertInfo*> is to avoid memory-leaks. CertList | |
| 127 // contains a list of CertInfo pointers and users don't have to worry about | |
| 128 // freeing those pointers. On the other hand, if you use vector<CertInfo> | |
| 129 // instead, it results in unwanted copying of CertInfo objects around. | |
| 130 class CertList { | |
| 131 public: | |
| 132 // Constructor | |
| 133 CertList() {} | |
| 134 | |
| 135 // Destructor | |
| 136 ~CertList() { | |
| 137 for (unsigned int inx = 0; inx < cert_list_.size(); ++inx) | |
| 138 delete cert_list_[inx]; | |
| 139 cert_list_.clear(); | |
| 140 } | |
| 141 | |
| 142 // size() returns the number of certificates in this CertList | |
| 143 size_t size() { | |
| 144 return cert_list_.size(); | |
| 145 } | |
| 146 | |
| 147 // AddCertificate() is used to add a certificate to CertList. | |
| 148 // NOTE that once a certificate is added, CertList takes ownership of that | |
| 149 // CertInfo object. | |
| 150 void AddCertificate(CertInfo* cert) { | |
| 151 cert_list_.push_back(cert); | |
| 152 } | |
| 153 | |
| 154 // FindFirstCert() finds the first certificate that exactly matches the given | |
| 155 // criteria. If allow_test_variant is true, the company name will also be | |
| 156 // deemed valid if it equals company_name_to_match + " (TEST)". | |
| 157 void FindFirstCert(CertInfo** result_cert_info, | |
| 158 const CString &company_name_to_match, | |
| 159 const CString &orgn_unit_to_match, | |
| 160 const CString &trust_authority_to_match, | |
| 161 bool allow_test_variant, | |
| 162 bool check_cert_is_valid_now); | |
| 163 | |
| 164 typedef std::vector<CertInfo*> CertInfoList; | |
| 165 | |
| 166 private: | |
| 167 CertInfoList cert_list_; | |
| 168 }; | |
| 169 | |
| 170 | |
| 171 // ExtractAllCertificatesFromSignature() takes in a signed file, extracts all | |
| 172 // the certificates related to its signature and returns them in a CertList | |
| 173 // object. | |
| 174 void ExtractAllCertificatesFromSignature(const wchar_t* signed_file, | |
| 175 CertList* cert_list); | |
| 176 | |
| 177 // Returns true if the signee is Google by exactly matching the first CN name | |
| 178 // against a well-defined string, currently "Google Inc". | |
| 179 bool VerifySigneeIsGoogle(const wchar_t* signed_file); | |
| 180 | |
| 181 // Returns S_OK if a given signed file contains a signature | |
| 182 // that could be successfully verified using one of the trust providers | |
| 183 // IE relies on. This means that, whoever signed the file, they should've signed | |
| 184 // using certificate issued by a well-known (to IE) trust provider like | |
| 185 // Verisign, Inc. | |
| 186 HRESULT VerifySignature(const wchar_t* signed_file, bool allow_network_check); | |
| 187 | |
| 188 // Returns true if a given signed file contains a valid signature. | |
| 189 inline bool SignatureIsValid(const wchar_t* signed_file, | |
| 190 bool allow_network_check) { | |
| 191 return VerifySignature(signed_file, allow_network_check) == S_OK; | |
| 192 } | |
| 193 | |
| 194 // Gets the timestamp for the file's signature. | |
| 195 HRESULT GetSigningTime(const wchar_t* signed_file, SYSTEMTIME* signing_time); | |
| 196 | |
| 197 // Verifies that the file was signed within the specified number of days. | |
| 198 HRESULT VerifyFileSignedWithinDays(const wchar_t* signed_file, int days); | |
| 199 | |
| 200 } // namespace omaha | |
| 201 | |
| 202 #endif // OMAHA_COMMON_SIGNATUREVALIDATOR_H__ | |
| OLD | NEW |