1// Copyright (c) 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/cert/x509_cert_types.h"
6
7#include "base/basictypes.h"
8#include "base/strings/string_piece.h"
9#include "base/time/time.h"
10#include "net/test/test_certificate_data.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace net {
14
15namespace {
16
17#if defined(OS_MACOSX) && !defined(OS_IOS)
18TEST(X509TypesTest, Matching) {
19  CertPrincipal spamco;
20  spamco.common_name = "SpamCo Dept. Of Certificization";
21  spamco.country_name = "EB";
22  spamco.organization_names.push_back("SpamCo Holding Company, LLC");
23  spamco.organization_names.push_back("SpamCo Evil Masterminds");
24  spamco.organization_unit_names.push_back("Class Z Obfuscation Authority");
25  ASSERT_TRUE(spamco.Matches(spamco));
26
27  CertPrincipal bogus;
28  EXPECT_FALSE(bogus.Matches(spamco));
29  EXPECT_FALSE(spamco.Matches(bogus));
30
31  bogus = spamco;
32  EXPECT_TRUE(bogus.Matches(spamco));
33  EXPECT_TRUE(spamco.Matches(bogus));
34
35  bogus.organization_names.erase(bogus.organization_names.begin(),
36                                 bogus.organization_names.end());
37  EXPECT_FALSE(bogus.Matches(spamco));
38  EXPECT_FALSE(spamco.Matches(bogus));
39
40  bogus.organization_names.push_back("SpamCo Holding Company, LLC");
41  bogus.organization_names.push_back("SpamCo Evil Masterminds");
42  EXPECT_TRUE(bogus.Matches(spamco));
43  EXPECT_TRUE(spamco.Matches(bogus));
44
45  bogus.locality_name = "Elbosdorf";
46  EXPECT_FALSE(bogus.Matches(spamco));
47  EXPECT_FALSE(spamco.Matches(bogus));
48
49  bogus.locality_name = "";
50  bogus.organization_unit_names.push_back("Q Division");
51  EXPECT_FALSE(bogus.Matches(spamco));
52  EXPECT_FALSE(spamco.Matches(bogus));
53}
54#endif
55
56#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
57TEST(X509TypesTest, ParseDNVerisign) {
58  CertPrincipal verisign;
59  EXPECT_TRUE(verisign.ParseDistinguishedName(VerisignDN, sizeof(VerisignDN)));
60  EXPECT_EQ("", verisign.common_name);
61  EXPECT_EQ("US", verisign.country_name);
62  ASSERT_EQ(1U, verisign.organization_names.size());
63  EXPECT_EQ("VeriSign, Inc.", verisign.organization_names[0]);
64  ASSERT_EQ(1U, verisign.organization_unit_names.size());
65  EXPECT_EQ("Class 1 Public Primary Certification Authority",
66            verisign.organization_unit_names[0]);
67}
68
69TEST(X509TypesTest, ParseDNStartcom) {
70  CertPrincipal startcom;
71  EXPECT_TRUE(startcom.ParseDistinguishedName(StartComDN, sizeof(StartComDN)));
72  EXPECT_EQ("StartCom Certification Authority", startcom.common_name);
73  EXPECT_EQ("IL", startcom.country_name);
74  ASSERT_EQ(1U, startcom.organization_names.size());
75  EXPECT_EQ("StartCom Ltd.", startcom.organization_names[0]);
76  ASSERT_EQ(1U, startcom.organization_unit_names.size());
77  EXPECT_EQ("Secure Digital Certificate Signing",
78            startcom.organization_unit_names[0]);
79}
80
81TEST(X509TypesTest, ParseDNUserTrust) {
82  CertPrincipal usertrust;
83  EXPECT_TRUE(usertrust.ParseDistinguishedName(UserTrustDN,
84                                               sizeof(UserTrustDN)));
85  EXPECT_EQ("UTN-USERFirst-Client Authentication and Email",
86            usertrust.common_name);
87  EXPECT_EQ("US", usertrust.country_name);
88  EXPECT_EQ("UT", usertrust.state_or_province_name);
89  EXPECT_EQ("Salt Lake City", usertrust.locality_name);
90  ASSERT_EQ(1U, usertrust.organization_names.size());
91  EXPECT_EQ("The USERTRUST Network", usertrust.organization_names[0]);
92  ASSERT_EQ(1U, usertrust.organization_unit_names.size());
93  EXPECT_EQ("http://www.usertrust.com",
94            usertrust.organization_unit_names[0]);
95}
96
97TEST(X509TypesTest, ParseDNTurkTrust) {
98  // Note: This tests parsing UTF8STRINGs.
99  CertPrincipal turktrust;
100  EXPECT_TRUE(turktrust.ParseDistinguishedName(TurkTrustDN,
101                                               sizeof(TurkTrustDN)));
102  EXPECT_EQ("TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı",
103            turktrust.common_name);
104  EXPECT_EQ("TR", turktrust.country_name);
105  EXPECT_EQ("Ankara", turktrust.locality_name);
106  ASSERT_EQ(1U, turktrust.organization_names.size());
107  EXPECT_EQ("TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005",
108            turktrust.organization_names[0]);
109}
110
111TEST(X509TypesTest, ParseDNATrust) {
112  // Note: This tests parsing 16-bit BMPSTRINGs.
113  CertPrincipal atrust;
114  EXPECT_TRUE(atrust.ParseDistinguishedName(ATrustQual01DN,
115                                            sizeof(ATrustQual01DN)));
116  EXPECT_EQ("A-Trust-Qual-01",
117            atrust.common_name);
118  EXPECT_EQ("AT", atrust.country_name);
119  ASSERT_EQ(1U, atrust.organization_names.size());
120  EXPECT_EQ("A-Trust Ges. für Sicherheitssysteme im elektr. Datenverkehr GmbH",
121            atrust.organization_names[0]);
122  ASSERT_EQ(1U, atrust.organization_unit_names.size());
123  EXPECT_EQ("A-Trust-Qual-01",
124            atrust.organization_unit_names[0]);
125}
126
127TEST(X509TypesTest, ParseDNEntrust) {
128  // Note: This tests parsing T61STRINGs and fields with multiple values.
129  CertPrincipal entrust;
130  EXPECT_TRUE(entrust.ParseDistinguishedName(EntrustDN,
131                                             sizeof(EntrustDN)));
132  EXPECT_EQ("Entrust.net Certification Authority (2048)",
133            entrust.common_name);
134  EXPECT_EQ("", entrust.country_name);
135  ASSERT_EQ(1U, entrust.organization_names.size());
136  EXPECT_EQ("Entrust.net",
137            entrust.organization_names[0]);
138  ASSERT_EQ(2U, entrust.organization_unit_names.size());
139  EXPECT_EQ("www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)",
140            entrust.organization_unit_names[0]);
141  EXPECT_EQ("(c) 1999 Entrust.net Limited",
142            entrust.organization_unit_names[1]);
143}
144#endif
145
146const struct CertDateTestData {
147  CertDateFormat format;
148  const char* date_string;
149  bool is_valid;
150  base::Time::Exploded expected_result;
151} kCertDateTimeData[] = {
152  { CERT_DATE_FORMAT_UTC_TIME,
153    "120101000000Z",
154    true,
155    { 2012, 1, 0, 1, 0, 0, 0 } },
156  { CERT_DATE_FORMAT_GENERALIZED_TIME,
157    "20120101000000Z",
158    true,
159    { 2012, 1, 0, 1, 0, 0, 0 } },
160  { CERT_DATE_FORMAT_UTC_TIME,
161    "490101000000Z",
162    true,
163    { 2049, 1, 0, 1, 0, 0, 0 } },
164  { CERT_DATE_FORMAT_UTC_TIME,
165    "500101000000Z",
166    true,
167    { 1950, 1, 0, 1, 0, 0, 0 } },
168  { CERT_DATE_FORMAT_GENERALIZED_TIME,
169    "19500101000000Z",
170    true,
171    { 1950, 1, 0, 1, 0, 0, 0 } },
172  { CERT_DATE_FORMAT_UTC_TIME,
173    "AB0101000000Z",
174    false,
175    { 0 } },
176  { CERT_DATE_FORMAT_GENERALIZED_TIME,
177    "19AB0101000000Z",
178    false,
179    { 0 } },
180  { CERT_DATE_FORMAT_UTC_TIME,
181    "",
182    false,
183    { 0 } },
184  { CERT_DATE_FORMAT_UTC_TIME,
185    "A",
186    false,
187    { 0 } },
188 { CERT_DATE_FORMAT_GENERALIZED_TIME,
189    "20121301000000Z",
190    false,
191    { 0 } },
192 { CERT_DATE_FORMAT_GENERALIZED_TIME,
193    "20120101123000Z",
194    true,
195    { 2012, 1, 0, 1, 12, 30, 0 } },
196};
197
198// GTest pretty printer.
199void PrintTo(const CertDateTestData& data, std::ostream* os) {
200  *os << " format: " << data.format
201      << "; date string: " << base::StringPiece(data.date_string)
202      << "; valid: " << data.is_valid
203      << "; expected date: "
204      << (data.is_valid ?
205              base::Time::FromUTCExploded(data.expected_result)
206                  .ToInternalValue() :
207              0U);
208}
209
210class X509CertTypesDateTest : public testing::TestWithParam<CertDateTestData> {
211  public:
212    virtual ~X509CertTypesDateTest() {}
213    virtual void SetUp() {
214      test_data_ = GetParam();
215    }
216
217  protected:
218    CertDateTestData test_data_;
219};
220
221TEST_P(X509CertTypesDateTest, Parse) {
222  base::Time parsed_date;
223  bool parsed = ParseCertificateDate(
224      test_data_.date_string, test_data_.format, &parsed_date);
225  EXPECT_EQ(test_data_.is_valid, parsed);
226  if (!test_data_.is_valid)
227    return;
228  // Convert the expected value to a base::Time(). This ensures that systems
229  // systems that only support 32-bit times will pass the tests, by ensuring at
230  // least that the times have the same truncating behaviour.
231  // Note: Compared as internal values so that mismatches can be cleanly
232  // printed by GTest (eg: without PrintTo overrides).
233  EXPECT_EQ(base::Time::FromUTCExploded(test_data_.expected_result)
234                .ToInternalValue(),
235            parsed_date.ToInternalValue());
236}
237INSTANTIATE_TEST_CASE_P(,
238                        X509CertTypesDateTest,
239                        testing::ValuesIn(kCertDateTimeData));
240
241}  // namespace
242
243}  // namespace net
244