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.
ParseIntAndAdvance(const char ** field,size_t field_len,bool * ok)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
CertPrincipal()30 CertPrincipal::CertPrincipal() {
31 }
32
CertPrincipal(const std::string & name)33 CertPrincipal::CertPrincipal(const std::string& name) : common_name(name) {}
34
~CertPrincipal()35 CertPrincipal::~CertPrincipal() {
36 }
37
GetDisplayName() const38 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
CertPolicy()49 CertPolicy::CertPolicy() {
50 }
51
~CertPolicy()52 CertPolicy::~CertPolicy() {
53 }
54
Check(X509Certificate * cert) const55 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
Allow(X509Certificate * cert)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
Deny(X509Certificate * cert)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
HasAllowedCert() const88 bool CertPolicy::HasAllowedCert() const {
89 return !allowed_.empty();
90 }
91
HasDeniedCert() const92 bool CertPolicy::HasDeniedCert() const {
93 return !denied_.empty();
94 }
95
ParseCertificateDate(const base::StringPiece & raw_date,CertDateFormat format,base::Time * time)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