• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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