pkixcheck_CheckKeyUsage_tests.cpp (12698B)
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 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 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 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 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 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 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 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 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 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 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. 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 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 286 TEST_F(pkixcheck_CheckKeyUsage, trailingData) 287 { 288 static uint8_t keyUsageWithTrailingDataData[] = { 289 0x03/*BIT STRING*/, 0x02/*LENGTH=2*/, 7/*unused bits*/, 0x80, 290 // The BIT STRING has already ended, but there's trailing data 291 0xab, 0xba 292 }; 293 static const Input keyUsageWithTrailingDataBytes(keyUsageWithTrailingDataData); 294 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeEndEntity, 295 &keyUsageWithTrailingDataBytes, 296 KeyUsage::digitalSignature)); 297 ASSERT_BAD(CheckKeyUsage(EndEntityOrCA::MustBeCA, 298 &keyUsageWithTrailingDataBytes, 299 KeyUsage::digitalSignature)); 300 }