| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/cert/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
| 6 | 6 |
| 7 #include <CommonCrypto/CommonDigest.h> | 7 #include <CommonCrypto/CommonDigest.h> |
| 8 #include <CoreServices/CoreServices.h> | 8 #include <CoreServices/CoreServices.h> |
| 9 #include <Security/Security.h> | 9 #include <Security/Security.h> |
| 10 | 10 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 namespace net { | 29 namespace net { |
| 30 | 30 |
| 31 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. | 31 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. |
| 32 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 | 32 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 |
| 33 #pragma clang diagnostic push | 33 #pragma clang diagnostic push |
| 34 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 34 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 void GetCertDistinguishedName( | 38 bool GetCertDistinguishedName( |
| 39 const x509_util::CSSMCachedCertificate& cached_cert, | 39 const x509_util::CSSMCachedCertificate& cached_cert, |
| 40 const CSSM_OID* oid, | 40 const CSSM_OID* oid, |
| 41 CertPrincipal* result) { | 41 CertPrincipal* result) { |
| 42 x509_util::CSSMFieldValue distinguished_name; | 42 x509_util::CSSMFieldValue distinguished_name; |
| 43 OSStatus status = cached_cert.GetField(oid, &distinguished_name); | 43 OSStatus status = cached_cert.GetField(oid, &distinguished_name); |
| 44 if (status || !distinguished_name.field()) | 44 if (status || !distinguished_name.field()) |
| 45 return; | 45 return false; |
| 46 result->ParseDistinguishedName(distinguished_name.field()->Data, | 46 result->ParseDistinguishedName(distinguished_name.field()->Data, |
| 47 distinguished_name.field()->Length); | 47 distinguished_name.field()->Length); |
| 48 return true; |
| 48 } | 49 } |
| 49 | 50 |
| 50 bool IsCertIssuerInEncodedList(X509Certificate::OSCertHandle cert_handle, | 51 bool IsCertIssuerInEncodedList(X509Certificate::OSCertHandle cert_handle, |
| 51 const std::vector<std::string>& issuers) { | 52 const std::vector<std::string>& issuers) { |
| 52 x509_util::CSSMCachedCertificate cached_cert; | 53 x509_util::CSSMCachedCertificate cached_cert; |
| 53 if (cached_cert.Init(cert_handle) != CSSM_OK) | 54 if (cached_cert.Init(cert_handle) != CSSM_OK) |
| 54 return false; | 55 return false; |
| 55 | 56 |
| 56 x509_util::CSSMFieldValue distinguished_name; | 57 x509_util::CSSMFieldValue distinguished_name; |
| 57 OSStatus status = cached_cert.GetField(&CSSMOID_X509V1IssuerNameStd, | 58 OSStatus status = cached_cert.GetField(&CSSMOID_X509V1IssuerNameStd, |
| 58 &distinguished_name); | 59 &distinguished_name); |
| 59 if (status || !distinguished_name.field()) | 60 if (status || !distinguished_name.field()) |
| 60 return false; | 61 return false; |
| 61 | 62 |
| 62 base::StringPiece name_piece( | 63 base::StringPiece name_piece( |
| 63 reinterpret_cast<const char*>(distinguished_name.field()->Data), | 64 reinterpret_cast<const char*>(distinguished_name.field()->Data), |
| 64 static_cast<size_t>(distinguished_name.field()->Length)); | 65 static_cast<size_t>(distinguished_name.field()->Length)); |
| 65 | 66 |
| 66 for (std::vector<std::string>::const_iterator it = issuers.begin(); | 67 for (std::vector<std::string>::const_iterator it = issuers.begin(); |
| 67 it != issuers.end(); ++it) { | 68 it != issuers.end(); ++it) { |
| 68 base::StringPiece issuer_piece(*it); | 69 base::StringPiece issuer_piece(*it); |
| 69 if (name_piece == issuer_piece) | 70 if (name_piece == issuer_piece) |
| 70 return true; | 71 return true; |
| 71 } | 72 } |
| 72 | 73 |
| 73 return false; | 74 return false; |
| 74 } | 75 } |
| 75 | 76 |
| 76 void GetCertDateForOID(const x509_util::CSSMCachedCertificate& cached_cert, | 77 bool GetCertDateForOID(const x509_util::CSSMCachedCertificate& cached_cert, |
| 77 const CSSM_OID* oid, | 78 const CSSM_OID* oid, |
| 78 Time* result) { | 79 Time* result) { |
| 79 *result = Time(); | 80 *result = Time(); |
| 80 | 81 |
| 81 x509_util::CSSMFieldValue field; | 82 x509_util::CSSMFieldValue field; |
| 82 OSStatus status = cached_cert.GetField(oid, &field); | 83 OSStatus status = cached_cert.GetField(oid, &field); |
| 83 if (status) | 84 if (status) |
| 84 return; | 85 return false; |
| 85 | 86 |
| 86 const CSSM_X509_TIME* x509_time = field.GetAs<CSSM_X509_TIME>(); | 87 const CSSM_X509_TIME* x509_time = field.GetAs<CSSM_X509_TIME>(); |
| 87 if (x509_time->timeType != BER_TAG_UTC_TIME && | 88 if (x509_time->timeType != BER_TAG_UTC_TIME && |
| 88 x509_time->timeType != BER_TAG_GENERALIZED_TIME) { | 89 x509_time->timeType != BER_TAG_GENERALIZED_TIME) { |
| 89 LOG(ERROR) << "Unsupported date/time format " | 90 LOG(ERROR) << "Unsupported date/time format " |
| 90 << x509_time->timeType; | 91 << x509_time->timeType; |
| 91 return; | 92 return false; |
| 92 } | 93 } |
| 93 | 94 |
| 94 base::StringPiece time_string( | 95 base::StringPiece time_string( |
| 95 reinterpret_cast<const char*>(x509_time->time.Data), | 96 reinterpret_cast<const char*>(x509_time->time.Data), |
| 96 x509_time->time.Length); | 97 x509_time->time.Length); |
| 97 CertDateFormat format = x509_time->timeType == BER_TAG_UTC_TIME ? | 98 CertDateFormat format = x509_time->timeType == BER_TAG_UTC_TIME ? |
| 98 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; | 99 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; |
| 99 if (!ParseCertificateDate(time_string, format, result)) | 100 if (!ParseCertificateDate(time_string, format, result)) { |
| 100 LOG(ERROR) << "Invalid certificate date/time " << time_string; | 101 LOG(ERROR) << "Invalid certificate date/time " << time_string; |
| 102 return false; |
| 103 } |
| 104 return true; |
| 101 } | 105 } |
| 102 | 106 |
| 103 std::string GetCertSerialNumber( | 107 std::string GetCertSerialNumber( |
| 104 const x509_util::CSSMCachedCertificate& cached_cert) { | 108 const x509_util::CSSMCachedCertificate& cached_cert) { |
| 105 x509_util::CSSMFieldValue serial_number; | 109 x509_util::CSSMFieldValue serial_number; |
| 106 OSStatus status = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, | 110 OSStatus status = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, |
| 107 &serial_number); | 111 &serial_number); |
| 108 if (status || !serial_number.field()) | 112 if (status || !serial_number.field()) |
| 109 return std::string(); | 113 return std::string(); |
| 110 | 114 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 if (IsValidOSCertHandle(cert)) { | 185 if (IsValidOSCertHandle(cert)) { |
| 182 CFRetain(cert); | 186 CFRetain(cert); |
| 183 output->push_back(cert); | 187 output->push_back(cert); |
| 184 } | 188 } |
| 185 } | 189 } |
| 186 } | 190 } |
| 187 } | 191 } |
| 188 | 192 |
| 189 } // namespace | 193 } // namespace |
| 190 | 194 |
| 191 void X509Certificate::Initialize() { | 195 bool X509Certificate::Initialize() { |
| 192 x509_util::CSSMCachedCertificate cached_cert; | 196 x509_util::CSSMCachedCertificate cached_cert; |
| 193 if (cached_cert.Init(cert_handle_) == CSSM_OK) { | 197 if (cached_cert.Init(cert_handle_) != CSSM_OK) |
| 194 GetCertDistinguishedName(cached_cert, &CSSMOID_X509V1SubjectNameStd, | 198 return false; |
| 195 &subject_); | 199 serial_number_ = GetCertSerialNumber(cached_cert); |
| 196 GetCertDistinguishedName(cached_cert, &CSSMOID_X509V1IssuerNameStd, | 200 |
| 197 &issuer_); | 201 return (!serial_number_.empty() && |
| 198 GetCertDateForOID(cached_cert, &CSSMOID_X509V1ValidityNotBefore, | 202 GetCertDistinguishedName(cached_cert, &CSSMOID_X509V1SubjectNameStd, |
| 199 &valid_start_); | 203 &subject_) && |
| 200 GetCertDateForOID(cached_cert, &CSSMOID_X509V1ValidityNotAfter, | 204 GetCertDistinguishedName(cached_cert, &CSSMOID_X509V1IssuerNameStd, |
| 201 &valid_expiry_); | 205 &issuer_) && |
| 202 serial_number_ = GetCertSerialNumber(cached_cert); | 206 GetCertDateForOID(cached_cert, &CSSMOID_X509V1ValidityNotBefore, |
| 203 } | 207 &valid_start_) && |
| 208 GetCertDateForOID(cached_cert, &CSSMOID_X509V1ValidityNotAfter, |
| 209 &valid_expiry_)); |
| 204 } | 210 } |
| 205 | 211 |
| 206 bool X509Certificate::IsIssuedByEncoded( | 212 bool X509Certificate::IsIssuedByEncoded( |
| 207 const std::vector<std::string>& valid_issuers) { | 213 const std::vector<std::string>& valid_issuers) { |
| 208 if (IsCertIssuerInEncodedList(cert_handle_, valid_issuers)) | 214 if (IsCertIssuerInEncodedList(cert_handle_, valid_issuers)) |
| 209 return true; | 215 return true; |
| 210 | 216 |
| 211 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); | 217 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); |
| 212 it != intermediate_ca_certs_.end(); ++it) { | 218 it != intermediate_ca_certs_.end(); ++it) { |
| 213 if (IsCertIssuerInEncodedList(*it, valid_issuers)) | 219 if (IsCertIssuerInEncodedList(*it, valid_issuers)) |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 return false; | 512 return false; |
| 507 | 513 |
| 508 if (CSSM_CL_CertVerify(cl_handle, 0, &cert_data, &cert_data, NULL, 0)) | 514 if (CSSM_CL_CertVerify(cl_handle, 0, &cert_data, &cert_data, NULL, 0)) |
| 509 return false; | 515 return false; |
| 510 return true; | 516 return true; |
| 511 } | 517 } |
| 512 | 518 |
| 513 #pragma clang diagnostic pop // "-Wdeprecated-declarations" | 519 #pragma clang diagnostic pop // "-Wdeprecated-declarations" |
| 514 | 520 |
| 515 } // namespace net | 521 } // namespace net |
| OLD | NEW |