OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "net/base/x509_certificate.h" | 5 #include "net/base/x509_certificate.h" |
6 | 6 |
7 #include <cert.h> | 7 #include <cert.h> |
8 #include <cryptohi.h> | 8 #include <cryptohi.h> |
9 #include <keyhi.h> | 9 #include <keyhi.h> |
10 #include <nss.h> | 10 #include <nss.h> |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 case SEC_ERROR_EXTENSION_VALUE_INVALID: | 161 case SEC_ERROR_EXTENSION_VALUE_INVALID: |
162 return CERT_STATUS_INVALID; | 162 return CERT_STATUS_INVALID; |
163 default: | 163 default: |
164 return 0; | 164 return 0; |
165 } | 165 } |
166 } | 166 } |
167 | 167 |
168 // Saves some information about the certificate chain cert_list in | 168 // Saves some information about the certificate chain cert_list in |
169 // *verify_result. The caller MUST initialize *verify_result before calling | 169 // *verify_result. The caller MUST initialize *verify_result before calling |
170 // this function. | 170 // this function. |
171 // Note that cert_list[0] is the end entity certificate and cert_list doesn't | 171 // Note that cert_list[0] is the end entity certificate. |
172 // contain the root CA certificate. | |
173 void GetCertChainInfo(CERTCertList* cert_list, | 172 void GetCertChainInfo(CERTCertList* cert_list, |
| 173 CERTCertificate* root_cert, |
174 CertVerifyResult* verify_result) { | 174 CertVerifyResult* verify_result) { |
175 // NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the | 175 // NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the |
176 // NSS version currently in use: | 176 // NSS version currently in use: |
177 // 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*) | 177 // 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*) |
178 // 2. use ident libnss3.so* for the library's version | 178 // 2. use ident libnss3.so* for the library's version |
179 DCHECK(cert_list); | 179 DCHECK(cert_list); |
| 180 |
| 181 CERTCertificate* verified_cert = NULL; |
| 182 std::vector<CERTCertificate*> verified_chain; |
180 int i = 0; | 183 int i = 0; |
181 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); | 184 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); |
182 !CERT_LIST_END(node, cert_list); | 185 !CERT_LIST_END(node, cert_list); |
183 node = CERT_LIST_NEXT(node), i++) { | 186 node = CERT_LIST_NEXT(node), ++i) { |
| 187 if (i == 0) { |
| 188 verified_cert = node->cert; |
| 189 } else { |
| 190 verified_chain.push_back(node->cert); |
| 191 } |
184 SECAlgorithmID& signature = node->cert->signature; | 192 SECAlgorithmID& signature = node->cert->signature; |
185 SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm); | 193 SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm); |
186 switch (oid_tag) { | 194 switch (oid_tag) { |
187 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: | 195 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: |
188 verify_result->has_md5 = true; | 196 verify_result->has_md5 = true; |
189 if (i != 0) | 197 if (i != 0) |
190 verify_result->has_md5_ca = true; | 198 verify_result->has_md5_ca = true; |
191 break; | 199 break; |
192 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: | 200 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: |
193 verify_result->has_md2 = true; | 201 verify_result->has_md2 = true; |
194 if (i != 0) | 202 if (i != 0) |
195 verify_result->has_md2_ca = true; | 203 verify_result->has_md2_ca = true; |
196 break; | 204 break; |
197 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: | 205 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: |
198 verify_result->has_md4 = true; | 206 verify_result->has_md4 = true; |
199 break; | 207 break; |
200 default: | 208 default: |
201 break; | 209 break; |
202 } | 210 } |
203 } | 211 } |
| 212 |
| 213 if (root_cert) |
| 214 verified_chain.push_back(root_cert); |
| 215 verify_result->verified_cert = |
| 216 X509Certificate::CreateFromHandle(verified_cert, verified_chain); |
204 } | 217 } |
205 | 218 |
206 // IsKnownRoot returns true if the given certificate is one that we believe | 219 // IsKnownRoot returns true if the given certificate is one that we believe |
207 // is a standard (as opposed to user-installed) root. | 220 // is a standard (as opposed to user-installed) root. |
208 bool IsKnownRoot(CERTCertificate* root) { | 221 bool IsKnownRoot(CERTCertificate* root) { |
209 if (!root->slot) | 222 if (!root->slot) |
210 return false; | 223 return false; |
211 | 224 |
212 // This magic name is taken from | 225 // This magic name is taken from |
213 // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/b
uiltins/constants.c&rev=1.13&mark=86,89#79 | 226 // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/b
uiltins/constants.c&rev=1.13&mark=86,89#79 |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 int cert_status = MapCertErrorToCertStatus(err); | 817 int cert_status = MapCertErrorToCertStatus(err); |
805 if (cert_status) { | 818 if (cert_status) { |
806 verify_result->cert_status |= cert_status; | 819 verify_result->cert_status |= cert_status; |
807 return MapCertStatusToNetError(verify_result->cert_status); | 820 return MapCertStatusToNetError(verify_result->cert_status); |
808 } | 821 } |
809 // |err| is not a certificate error. | 822 // |err| is not a certificate error. |
810 return MapSecurityError(err); | 823 return MapSecurityError(err); |
811 } | 824 } |
812 | 825 |
813 GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain, | 826 GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain, |
| 827 cvout[cvout_trust_anchor_index].value.pointer.cert, |
814 verify_result); | 828 verify_result); |
815 if (IsCertStatusError(verify_result->cert_status)) | 829 if (IsCertStatusError(verify_result->cert_status)) |
816 return MapCertStatusToNetError(verify_result->cert_status); | 830 return MapCertStatusToNetError(verify_result->cert_status); |
817 | 831 |
818 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, | 832 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, |
819 cvout[cvout_trust_anchor_index].value.pointer.cert, | 833 cvout[cvout_trust_anchor_index].value.pointer.cert, |
820 &verify_result->public_key_hashes); | 834 &verify_result->public_key_hashes); |
821 | 835 |
822 verify_result->is_issued_by_known_root = | 836 verify_result->is_issued_by_known_root = |
823 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); | 837 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 | 1009 |
996 // static | 1010 // static |
997 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, | 1011 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, |
998 Pickle* pickle) { | 1012 Pickle* pickle) { |
999 return pickle->WriteData( | 1013 return pickle->WriteData( |
1000 reinterpret_cast<const char*>(cert_handle->derCert.data), | 1014 reinterpret_cast<const char*>(cert_handle->derCert.data), |
1001 cert_handle->derCert.len); | 1015 cert_handle->derCert.len); |
1002 } | 1016 } |
1003 | 1017 |
1004 } // namespace net | 1018 } // namespace net |
OLD | NEW |