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_cert_types.h"
6
7#include <cstdlib>
8#include <cstring>
9
10#include "base/logging.h"
11#include "base/strings/string_number_conversions.h"
12#include "base/strings/string_piece.h"
13#include "base/time/time.h"
14#include "net/cert/x509_certificate.h"
15
16namespace net {
17
18namespace {
19
20// Helper for ParseCertificateDate. |*field| must contain at least
21// |field_len| characters. |*field| will be advanced by |field_len| on exit.
22// |*ok| is set to false if there is an error in parsing the number, but left
23// untouched otherwise. Returns the parsed integer.
24int ParseIntAndAdvance(const char** field, size_t field_len, bool* ok) {
25  int result = 0;
26  *ok &= base::StringToInt(base::StringPiece(*field, field_len), &result);
27  *field += field_len;
28  return result;
29}
30
31}
32
33CertPrincipal::CertPrincipal() {
34}
35
36CertPrincipal::CertPrincipal(const std::string& name) : common_name(name) {}
37
38CertPrincipal::~CertPrincipal() {
39}
40
41std::string CertPrincipal::GetDisplayName() const {
42  if (!common_name.empty())
43    return common_name;
44  if (!organization_names.empty())
45    return organization_names[0];
46  if (!organization_unit_names.empty())
47    return organization_unit_names[0];
48
49  return std::string();
50}
51
52bool ParseCertificateDate(const base::StringPiece& raw_date,
53                          CertDateFormat format,
54                          base::Time* time) {
55  size_t year_length = format == CERT_DATE_FORMAT_UTC_TIME ? 2 : 4;
56
57  if (raw_date.length() < 11 + year_length)
58    return false;
59
60  const char* field = raw_date.data();
61  bool valid = true;
62  base::Time::Exploded exploded = {0};
63
64  exploded.year =         ParseIntAndAdvance(&field, year_length, &valid);
65  exploded.month =        ParseIntAndAdvance(&field, 2, &valid);
66  exploded.day_of_month = ParseIntAndAdvance(&field, 2, &valid);
67  exploded.hour =         ParseIntAndAdvance(&field, 2, &valid);
68  exploded.minute =       ParseIntAndAdvance(&field, 2, &valid);
69  exploded.second =       ParseIntAndAdvance(&field, 2, &valid);
70  if (valid && year_length == 2)
71    exploded.year += exploded.year < 50 ? 2000 : 1900;
72
73  valid &= exploded.HasValidValues();
74
75  if (!valid)
76    return false;
77
78  *time = base::Time::FromUTCExploded(exploded);
79  return true;
80}
81
82}  // namespace net
83