Home | History | Annotate | Download | only in cert
      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
      3 // found in the LICENSE file.
      4 
      5 #include "net/cert/x509_util.h"
      6 #include "net/cert/x509_util_openssl.h"
      7 
      8 #include <algorithm>
      9 
     10 #include "base/logging.h"
     11 #include "base/strings/string_piece.h"
     12 #include "net/cert/x509_cert_types.h"
     13 
     14 namespace net {
     15 
     16 namespace x509_util {
     17 
     18 bool IsSupportedValidityRange(base::Time not_valid_before,
     19                               base::Time not_valid_after) {
     20   if (not_valid_before > not_valid_after)
     21     return false;
     22 
     23   // The validity field of a certificate can only encode years 1-9999.
     24 
     25   // Compute the base::Time values corresponding to Jan 1st,0001 and
     26   // Jan 1st, 10000 respectively. Done by using the pre-computed numbers
     27   // of days between these dates and the Unix epoch, i.e. Jan 1st, 1970,
     28   // using the following Python script:
     29   //
     30   //     from datetime import date as D
     31   //     print (D(1970,1,1)-D(1,1,1))        # -> 719162 days
     32   //     print (D(9999,12,31)-D(1970,1,1))   # -> 2932896 days
     33   //
     34   // Note: This ignores leap seconds, but should be enough in practice.
     35   //
     36   const int64 kDaysFromYear0001ToUnixEpoch = 719162;
     37   const int64 kDaysFromUnixEpochToYear10000 = 2932896 + 1;
     38   const base::Time kEpoch = base::Time::UnixEpoch();
     39   const base::Time kYear0001 = kEpoch -
     40       base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch);
     41   const base::Time kYear10000 = kEpoch +
     42       base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000);
     43 
     44   if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 ||
     45       not_valid_after < kYear0001 || not_valid_after >= kYear10000)
     46     return false;
     47 
     48   return true;
     49 }
     50 
     51 bool CreateDomainBoundCertEC(
     52     crypto::ECPrivateKey* key,
     53     const std::string& domain,
     54     uint32 serial_number,
     55     base::Time not_valid_before,
     56     base::Time not_valid_after,
     57     std::string* der_cert) {
     58   NOTIMPLEMENTED();
     59   return false;
     60 }
     61 
     62 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
     63                           const std::string& common_name,
     64                           uint32 serial_number,
     65                           base::Time not_valid_before,
     66                           base::Time not_valid_after,
     67                           std::string* der_encoded) {
     68   NOTIMPLEMENTED();
     69   return false;
     70 }
     71 
     72 bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name,
     73                                       int index,
     74                                       std::string* key,
     75                                       std::string* value) {
     76   X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index);
     77   if (!entry)
     78     return false;
     79 
     80   if (key) {
     81     ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(entry);
     82     key->assign(OBJ_nid2sn(OBJ_obj2nid(object)));
     83   }
     84 
     85   ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
     86   if (!data)
     87     return false;
     88 
     89   unsigned char* buf = NULL;
     90   int len = ASN1_STRING_to_UTF8(&buf, data);
     91   if (len <= 0)
     92     return false;
     93 
     94   value->assign(reinterpret_cast<const char*>(buf), len);
     95   OPENSSL_free(buf);
     96   return true;
     97 }
     98 
     99 bool ParsePrincipalValueByIndex(X509_NAME* name,
    100                                 int index,
    101                                 std::string* value) {
    102   return ParsePrincipalKeyAndValueByIndex(name, index, NULL, value);
    103 }
    104 
    105 bool ParsePrincipalValueByNID(X509_NAME* name, int nid, std::string* value) {
    106   int index = X509_NAME_get_index_by_NID(name, nid, -1);
    107   if (index < 0)
    108     return false;
    109 
    110   return ParsePrincipalValueByIndex(name, index, value);
    111 }
    112 
    113 bool ParseDate(ASN1_TIME* x509_time, base::Time* time) {
    114   if (!x509_time ||
    115       (x509_time->type != V_ASN1_UTCTIME &&
    116        x509_time->type != V_ASN1_GENERALIZEDTIME))
    117     return false;
    118 
    119   base::StringPiece str_date(reinterpret_cast<const char*>(x509_time->data),
    120                              x509_time->length);
    121 
    122   CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ?
    123       CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME;
    124   return ParseCertificateDate(str_date, format, time);
    125 }
    126 
    127 }  // namespace x509_util
    128 
    129 }  // namespace net
    130