1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This code is made available to you under your choice of the following sets
4 * of licensing terms:
5 */
6 /* This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
10 /* Copyright 2013 Mozilla Contributors
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24
25 #include "pkixgtest.h"
26
27 using namespace mozilla::pkix;
28 using namespace mozilla::pkix::test;
29
30 namespace mozilla { namespace pkix {
31
32 extern Result CheckKeyUsage(EndEntityOrCA endEntityOrCA,
33 const Input* encodedKeyUsage,
34 KeyUsage requiredKeyUsageIfPresent);
35
36 } } // namespace mozilla::pkix
37
38 class pkixcheck_CheckKeyUsage : public ::testing::Test { };
39
40 #define ASSERT_BAD(x) ASSERT_EQ(Result::ERROR_INADEQUATE_KEY_USAGE, x)
41
42 // Make it easy to define test data for the common, simplest cases.
43 #define NAMED_SIMPLE_KU(name, unusedBits, bits) \
44 const uint8_t name##_bytes[4] = { \
45 0x03/*BIT STRING*/, 0x02/*LENGTH=2*/, unusedBits, bits \
46 }; \
47 const Input name(name##_bytes);
48
49 static const Input empty_null;
50
51 // Note that keyCertSign is really the only interesting case for CA
52 // certificates since we don't support cRLSign.
53
TEST_F(pkixcheck_CheckKeyUsage,EE_none)54 TEST_F(pkixcheck_CheckKeyUsage, EE_none)
55 {
56 // The input Input is nullptr. This means the cert had no keyUsage
57 // extension. This is always valid because no key usage in an end-entity
58 // means that there are no key usage restrictions.
59
60 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
61 KeyUsage::noParticularKeyUsageRequired));
62 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
63 KeyUsage::digitalSignature));
64 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
65 KeyUsage::nonRepudiation));
66 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
67 KeyUsage::keyEncipherment));
68 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
69 KeyUsage::dataEncipherment));
70 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
71 KeyUsage::keyAgreement));
72 }
73
TEST_F(pkixcheck_CheckKeyUsage,EE_empty)74 TEST_F(pkixcheck_CheckKeyUsage, EE_empty)
75 {
76 // The input Input is empty. The cert had an empty keyUsage extension,
77 // which is syntactically invalid.
78 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &empty_null,
79 KeyUsage::digitalSignature));
80 static const uint8_t dummy = 0x00;
81 Input empty_nonnull;
82 ASSERT_EQ(Success, empty_nonnull.Init(&dummy, 0));
83 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &empty_nonnull,
84 KeyUsage::digitalSignature));
85 }
86
TEST_F(pkixcheck_CheckKeyUsage,CA_none)87 TEST_F(pkixcheck_CheckKeyUsage, CA_none)
88 {
89 // A CA certificate does not have a KU extension.
90 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
91 KeyUsage::keyCertSign));
92 }
93
TEST_F(pkixcheck_CheckKeyUsage,CA_empty)94 TEST_F(pkixcheck_CheckKeyUsage, CA_empty)
95 {
96 // A CA certificate has an empty KU extension.
97 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &empty_null,
98 KeyUsage::keyCertSign));
99 static const uint8_t dummy = 0x00;
100 Input empty_nonnull;
101 ASSERT_EQ(Success, empty_nonnull.Init(&dummy, 0));
102 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &empty_nonnull,
103 KeyUsage::keyCertSign));
104 }
105
TEST_F(pkixcheck_CheckKeyUsage,maxUnusedBits)106 TEST_F(pkixcheck_CheckKeyUsage, maxUnusedBits)
107 {
108 NAMED_SIMPLE_KU(encoded, 7, 0x80);
109 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &encoded,
110 KeyUsage::digitalSignature));
111 }
112
TEST_F(pkixcheck_CheckKeyUsage,tooManyUnusedBits)113 TEST_F(pkixcheck_CheckKeyUsage, tooManyUnusedBits)
114 {
115 static uint8_t oneValueByteData[] = {
116 0x03/*BIT STRING*/, 0x02/*LENGTH=2*/, 8/*unused bits*/, 0x80
117 };
118 static const Input oneValueByte(oneValueByteData);
119 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &oneValueByte,
120 KeyUsage::digitalSignature));
121
122 static uint8_t twoValueBytesData[] = {
123 0x03/*BIT STRING*/, 0x03/*LENGTH=3*/, 8/*unused bits*/, 0x01, 0x00
124 };
125 static const Input twoValueBytes(twoValueBytesData);
126 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &twoValueBytes,
127 KeyUsage::digitalSignature));
128 }
129
TEST_F(pkixcheck_CheckKeyUsage,NoValueBytes_NoPaddingBits)130 TEST_F(pkixcheck_CheckKeyUsage, NoValueBytes_NoPaddingBits)
131 {
132 static const uint8_t DER_BYTES[] = {
133 0x03/*BIT STRING*/, 0x01/*LENGTH=1*/, 0/*unused bits*/
134 };
135 static const Input DER(DER_BYTES);
136 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &DER,
137 KeyUsage::digitalSignature));
138 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &DER,
139 KeyUsage::keyCertSign));
140 }
141
TEST_F(pkixcheck_CheckKeyUsage,NoValueBytes_7PaddingBits)142 TEST_F(pkixcheck_CheckKeyUsage, NoValueBytes_7PaddingBits)
143 {
144 static const uint8_t DER_BYTES[] = {
145 0x03/*BIT STRING*/, 0x01/*LENGTH=1*/, 7/*unused bits*/
146 };
147 static const Input DER(DER_BYTES);
148 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &DER,
149 KeyUsage::digitalSignature));
150 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &DER,
151 KeyUsage::keyCertSign));
152 }
153
ASSERT_SimpleCase(uint8_t unusedBits,uint8_t bits,KeyUsage usage)154 void ASSERT_SimpleCase(uint8_t unusedBits, uint8_t bits, KeyUsage usage)
155 {
156 // Test that only the right bit is accepted for the usage for both EE and CA
157 // certs.
158 NAMED_SIMPLE_KU(good, unusedBits, bits);
159 ASSERT_EQ(Success,
160 CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &good, usage));
161 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeCA, &good, usage));
162
163 // We use (~bits >> unusedBits) << unusedBits) instead of using the same
164 // calculation that is in CheckKeyUsage to validate that the calculation in
165 // CheckKeyUsage is correct.
166
167 // Test that none of the other non-padding bits are mistaken for the given
168 // key usage in the single-byte value case.
169 uint8_t paddingBits = (static_cast<uint8_t>(~bits) >> unusedBits) << unusedBits;
170 NAMED_SIMPLE_KU(notGood, unusedBits, paddingBits);
171 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, ¬Good, usage));
172 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, ¬Good, usage));
173
174 // Test that none of the other non-padding bits are mistaken for the given
175 // key usage in the two-byte value case.
176 const uint8_t twoByteNotGoodData[] = {
177 0x03/*BIT STRING*/, 0x03/*LENGTH=3*/, unusedBits,
178 static_cast<uint8_t>(~bits),
179 static_cast<uint8_t>((0xFFu >> unusedBits) << unusedBits)
180 };
181 Input twoByteNotGood(twoByteNotGoodData);
182 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &twoByteNotGood,
183 usage));
184 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &twoByteNotGood, usage));
185 }
186
TEST_F(pkixcheck_CheckKeyUsage,simpleCases)187 TEST_F(pkixcheck_CheckKeyUsage, simpleCases)
188 {
189 ASSERT_SimpleCase(7, 0x80, KeyUsage::digitalSignature);
190 ASSERT_SimpleCase(6, 0x40, KeyUsage::nonRepudiation);
191 ASSERT_SimpleCase(5, 0x20, KeyUsage::keyEncipherment);
192 ASSERT_SimpleCase(4, 0x10, KeyUsage::dataEncipherment);
193 ASSERT_SimpleCase(3, 0x08, KeyUsage::keyAgreement);
194 }
195
196 // Only CAs are allowed to assert keyCertSign.
197 // End-entity certs may assert it along with other key usages if keyCertSign
198 // isn't the required key usage. This is for compatibility.
TEST_F(pkixcheck_CheckKeyUsage,keyCertSign)199 TEST_F(pkixcheck_CheckKeyUsage, keyCertSign)
200 {
201 NAMED_SIMPLE_KU(good, 2, 0x04);
202 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &good,
203 KeyUsage::keyCertSign));
204 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeCA, &good,
205 KeyUsage::keyCertSign));
206
207 // Test that none of the other non-padding bits are mistaken for the given
208 // key usage in the one-byte value case.
209 NAMED_SIMPLE_KU(notGood, 2, 0xFB);
210 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, ¬Good,
211 KeyUsage::keyCertSign));
212 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, ¬Good,
213 KeyUsage::keyCertSign));
214
215 // Test that none of the other non-padding bits are mistaken for the given
216 // key usage in the two-byte value case.
217 static uint8_t twoByteNotGoodData[] = {
218 0x03/*BIT STRING*/, 0x03/*LENGTH=3*/, 2/*unused bits*/, 0xFBu, 0xFCu
219 };
220 static const Input twoByteNotGood(twoByteNotGoodData);
221 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &twoByteNotGood,
222 KeyUsage::keyCertSign));
223 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &twoByteNotGood,
224 KeyUsage::keyCertSign));
225
226 // If an end-entity certificate does assert keyCertSign, this is allowed
227 // as long as that isn't the required key usage.
228 NAMED_SIMPLE_KU(digitalSignatureAndKeyCertSign, 2, 0x84);
229 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity,
230 &digitalSignatureAndKeyCertSign,
231 KeyUsage::digitalSignature));
232 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity,
233 &digitalSignatureAndKeyCertSign,
234 KeyUsage::keyCertSign));
235 }
236
TEST_F(pkixcheck_CheckKeyUsage,unusedBitNotZero)237 TEST_F(pkixcheck_CheckKeyUsage, unusedBitNotZero)
238 {
239 // single byte control case
240 static uint8_t controlOneValueByteData[] = {
241 0x03/*BIT STRING*/, 0x02/*LENGTH=2*/, 7/*unused bits*/, 0x80
242 };
243 static const Input controlOneValueByte(controlOneValueByteData);
244 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity,
245 &controlOneValueByte,
246 KeyUsage::digitalSignature));
247 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeCA,
248 &controlOneValueByte,
249 KeyUsage::digitalSignature));
250
251 // single-byte test case
252 static uint8_t oneValueByteData[] = {
253 0x03/*BIT STRING*/, 0x02/*LENGTH=2*/, 7/*unused bits*/, 0x80 | 0x01
254 };
255 static const Input oneValueByte(oneValueByteData);
256 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &oneValueByte,
257 KeyUsage::digitalSignature));
258 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &oneValueByte,
259 KeyUsage::digitalSignature));
260
261 // two-byte control case
262 static uint8_t controlTwoValueBytesData[] = {
263 0x03/*BIT STRING*/, 0x03/*LENGTH=3*/, 7/*unused bits*/,
264 0x80 | 0x01, 0x80
265 };
266 static const Input controlTwoValueBytes(controlTwoValueBytesData);
267 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeEndEntity,
268 &controlTwoValueBytes,
269 KeyUsage::digitalSignature));
270 ASSERT_EQ(Success, CheckKeyUsage(EndEntityOrCA::MustBeCA,
271 &controlTwoValueBytes,
272 KeyUsage::digitalSignature));
273
274 // two-byte test case
275 static uint8_t twoValueBytesData[] = {
276 0x03/*BIT STRING*/, 0x03/*LENGTH=3*/, 7/*unused bits*/,
277 0x80 | 0x01, 0x80 | 0x01
278 };
279 static const Input twoValueBytes(twoValueBytesData);
280 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, &twoValueBytes,
281 KeyUsage::digitalSignature));
282 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, &twoValueBytes,
283 KeyUsage::digitalSignature));
284 }
285