Home | History | Annotate | Download | only in base
      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