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 |