1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/base/x509_cert_types.h" 6 7 #include "net/base/x509_certificate.h" 8 #include "base/logging.h" 9 #include "base/string_number_conversions.h" 10 #include "base/string_piece.h" 11 #include "base/time.h" 12 13 namespace net { 14 15 namespace { 16 17 // Helper for ParseCertificateDate. |*field| must contain at least 18 // |field_len| characters. |*field| will be advanced by |field_len| on exit. 19 // |*ok| is set to false if there is an error in parsing the number, but left 20 // untouched otherwise. Returns the parsed integer. 21 int ParseIntAndAdvance(const char** field, size_t field_len, bool* ok) { 22 int result = 0; 23 *ok &= base::StringToInt(*field, *field + field_len, &result); 24 *field += field_len; 25 return result; 26 } 27 28 } // namespace 29 30 CertPrincipal::CertPrincipal() { 31 } 32 33 CertPrincipal::CertPrincipal(const std::string& name) : common_name(name) {} 34 35 CertPrincipal::~CertPrincipal() { 36 } 37 38 std::string CertPrincipal::GetDisplayName() const { 39 if (!common_name.empty()) 40 return common_name; 41 if (!organization_names.empty()) 42 return organization_names[0]; 43 if (!organization_unit_names.empty()) 44 return organization_unit_names[0]; 45 46 return std::string(); 47 } 48 49 CertPolicy::CertPolicy() { 50 } 51 52 CertPolicy::~CertPolicy() { 53 } 54 55 CertPolicy::Judgment CertPolicy::Check( 56 X509Certificate* cert) const { 57 // It shouldn't matter which set we check first, but we check denied first 58 // in case something strange has happened. 59 60 if (denied_.find(cert->fingerprint()) != denied_.end()) { 61 // DCHECK that the order didn't matter. 62 DCHECK(allowed_.find(cert->fingerprint()) == allowed_.end()); 63 return DENIED; 64 } 65 66 if (allowed_.find(cert->fingerprint()) != allowed_.end()) { 67 // DCHECK that the order didn't matter. 68 DCHECK(denied_.find(cert->fingerprint()) == denied_.end()); 69 return ALLOWED; 70 } 71 72 // We don't have a policy for this cert. 73 return UNKNOWN; 74 } 75 76 void CertPolicy::Allow(X509Certificate* cert) { 77 // Put the cert in the allowed set and (maybe) remove it from the denied set. 78 denied_.erase(cert->fingerprint()); 79 allowed_.insert(cert->fingerprint()); 80 } 81 82 void CertPolicy::Deny(X509Certificate* cert) { 83 // Put the cert in the denied set and (maybe) remove it from the allowed set. 84 allowed_.erase(cert->fingerprint()); 85 denied_.insert(cert->fingerprint()); 86 } 87 88 bool CertPolicy::HasAllowedCert() const { 89 return !allowed_.empty(); 90 } 91 92 bool CertPolicy::HasDeniedCert() const { 93 return !denied_.empty(); 94 } 95 96 bool ParseCertificateDate(const base::StringPiece& raw_date, 97 CertDateFormat format, 98 base::Time* time) { 99 size_t year_length = format == CERT_DATE_FORMAT_UTC_TIME ? 2 : 4; 100 101 if (raw_date.length() < 11 + year_length) 102 return false; 103 104 const char* field = raw_date.data(); 105 bool valid = true; 106 base::Time::Exploded exploded = {0}; 107 108 exploded.year = ParseIntAndAdvance(&field, year_length, &valid); 109 exploded.month = ParseIntAndAdvance(&field, 2, &valid); 110 exploded.day_of_month = ParseIntAndAdvance(&field, 2, &valid); 111 exploded.hour = ParseIntAndAdvance(&field, 2, &valid); 112 exploded.minute = ParseIntAndAdvance(&field, 2, &valid); 113 exploded.second = ParseIntAndAdvance(&field, 2, &valid); 114 if (valid && year_length == 2) 115 exploded.year += exploded.year < 50 ? 2000 : 1900; 116 117 valid &= exploded.HasValidValues(); 118 119 if (!valid) 120 return false; 121 122 *time = base::Time::FromUTCExploded(exploded); 123 return true; 124 } 125 126 } // namespace net 127