• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
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 <algorithm>
6 
7 #include "extended_key_usage.h"
8 #include "input.h"
9 #include <gtest/gtest.h>
10 
11 namespace bssl {
12 
13 namespace {
14 
15 // Helper method to check if an EKU is present in a std::vector of EKUs.
HasEKU(const std::vector<der::Input> & list,const der::Input & eku)16 bool HasEKU(const std::vector<der::Input>& list, const der::Input& eku) {
17   for (const auto& oid : list) {
18     if (oid == eku)
19       return true;
20   }
21   return false;
22 }
23 
24 // Check that we can read multiple EKUs from an extension.
TEST(ExtendedKeyUsageTest,ParseEKUExtension)25 TEST(ExtendedKeyUsageTest, ParseEKUExtension) {
26   // clang-format off
27   const uint8_t raw_extension_value[] = {
28       0x30, 0x14,  // SEQUENCE (20 bytes)
29       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
30       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,  // 1.3.6.1.5.5.7.3.1
31       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
32       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02  // 1.3.6.1.5.5.7.3.2
33       // end of SEQUENCE
34   };
35   // clang-format on
36   der::Input extension_value(raw_extension_value);
37 
38   std::vector<der::Input> ekus;
39   EXPECT_TRUE(ParseEKUExtension(extension_value, &ekus));
40 
41   EXPECT_EQ(2u, ekus.size());
42   EXPECT_TRUE(HasEKU(ekus, der::Input(kServerAuth)));
43   EXPECT_TRUE(HasEKU(ekus, der::Input(kClientAuth)));
44 }
45 
46 // Check that an extension with the same OID present multiple times doesn't
47 // cause an error.
TEST(ExtendedKeyUsageTest,RepeatedOid)48 TEST(ExtendedKeyUsageTest, RepeatedOid) {
49   // clang-format off
50   const uint8_t extension_bytes[] = {
51       0x30, 0x14,  // SEQUENCE (20 bytes)
52       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
53       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,  // 1.3.6.1.5.5.7.3.1
54       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
55       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01  // 1.3.6.1.5.5.7.3.1
56   };
57   // clang-format on
58   der::Input extension(extension_bytes);
59 
60   std::vector<der::Input> ekus;
61   EXPECT_TRUE(ParseEKUExtension(extension, &ekus));
62   EXPECT_EQ(2u, ekus.size());
63   for (const auto& eku : ekus) {
64     EXPECT_EQ(der::Input(kServerAuth), eku);
65   }
66 }
67 
68 // Check that parsing an EKU extension which contains a private OID doesn't
69 // cause an error.
TEST(ExtendedKeyUsageTest,ParseEKUExtensionGracefullyHandlesPrivateOids)70 TEST(ExtendedKeyUsageTest, ParseEKUExtensionGracefullyHandlesPrivateOids) {
71   // clang-format off
72   const uint8_t extension_bytes[] = {
73     0x30, 0x13,  // SEQUENCE (19 bytes)
74     0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
75     0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,  // 1.3.6.1.5.5.7.3.1
76     0x06, 0x07,  // OBJECT IDENTIFIER (7 bytes)
77     0x2B, 0x06, 0x01, 0x04, 0x01, 0xD6, 0x79  // 1.3.6.1.4.1.11129
78   };
79   // clang-format on
80   der::Input extension(extension_bytes);
81 
82   std::vector<der::Input> ekus;
83   EXPECT_TRUE(ParseEKUExtension(extension, &ekus));
84   EXPECT_EQ(2u, ekus.size());
85   EXPECT_TRUE(HasEKU(ekus, der::Input(kServerAuth)));
86 
87   const uint8_t google_oid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0xD6, 0x79};
88   der::Input google(google_oid);
89   EXPECT_TRUE(HasEKU(ekus, google));
90 }
91 
92 // Test a variety of bad inputs.
93 
94 // If the extension value has data following the sequence of oids, parsing it
95 // should fail.
TEST(ExtendedKeyUsageTest,ExtraData)96 TEST(ExtendedKeyUsageTest, ExtraData) {
97   // clang-format off
98   const uint8_t extra_data[] = {
99       0x30, 0x14,  // SEQUENCE (20 bytes)
100       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
101       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,  // 1.3.6.1.5.5.7.3.1
102       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
103       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,  // 1.3.6.1.5.5.7.3.2
104       // end of SEQUENCE
105       0x02, 0x01,  // INTEGER (1 byte)
106       0x01  // 1
107   };
108   // clang-format on
109 
110   std::vector<der::Input> ekus;
111   EXPECT_FALSE(ParseEKUExtension(der::Input(extra_data), &ekus));
112 }
113 
114 // Check that ParseEKUExtension only accepts a sequence containing only oids.
115 // This test case has an integer in the sequence (which should fail). A key
116 // difference between this test case and ExtendedKeyUsageTest.ExtraData is where
117 // the sequence ends - in this test case the integer is still part of the
118 // sequence, while in ExtendedKeyUsageTest.ExtraData the integer is after the
119 // sequence.
TEST(ExtendedKeyUsageTest,NotAnOid)120 TEST(ExtendedKeyUsageTest, NotAnOid) {
121   // clang-format off
122   const uint8_t not_an_oid[] = {
123       0x30, 0x0d,  // SEQUENCE (13 bytes)
124       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
125       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,  // 1.3.6.1.5.5.7.3.1
126       0x02, 0x01,  // INTEGER (1 byte)
127       0x01  // 1
128       // end of SEQUENCE
129   };
130   // clang-format on
131 
132   std::vector<der::Input> ekus;
133   EXPECT_FALSE(ParseEKUExtension(der::Input(not_an_oid), &ekus));
134 }
135 
136 // Checks that the list of oids passed to ParseEKUExtension are in a sequence,
137 // instead of one or more oid tag-length-values concatenated together.
TEST(ExtendedKeyUsageTest,NotASequence)138 TEST(ExtendedKeyUsageTest, NotASequence) {
139   // clang-format off
140   const uint8_t not_a_sequence[] = {
141       0x06, 0x08,  // OBJECT IDENTIFIER (8 bytes)
142       0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01  // 1.3.6.1.5.5.7.3.1
143   };
144   // clang-format on
145 
146   std::vector<der::Input> ekus;
147   EXPECT_FALSE(ParseEKUExtension(der::Input(not_a_sequence), &ekus));
148 }
149 
150 // A sequence passed into ParseEKUExtension must have at least one oid in it.
TEST(ExtendedKeyUsageTest,EmptySequence)151 TEST(ExtendedKeyUsageTest, EmptySequence) {
152   const uint8_t empty_sequence[] = {0x30, 0x00};  // SEQUENCE (0 bytes)
153 
154   std::vector<der::Input> ekus;
155   EXPECT_FALSE(ParseEKUExtension(der::Input(empty_sequence), &ekus));
156 }
157 
158 // The extension value must not be empty.
TEST(ExtendedKeyUsageTest,EmptyExtension)159 TEST(ExtendedKeyUsageTest, EmptyExtension) {
160   std::vector<der::Input> ekus;
161   EXPECT_FALSE(ParseEKUExtension(der::Input(), &ekus));
162 }
163 
164 }  // namespace
165 
166 }  // namespace net
167