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