Mirror of BoringSSL (grpc依赖)
https://boringssl.googlesource.com/boringssl
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.5 KiB
166 lines
5.5 KiB
// Copyright 2015 The Chromium Authors |
|
// Use of this source code is governed by a BSD-style license that can be |
|
// found in the LICENSE file. |
|
|
|
#include <algorithm> |
|
|
|
#include "extended_key_usage.h" |
|
#include "input.h" |
|
#include <gtest/gtest.h> |
|
|
|
namespace bssl { |
|
|
|
namespace { |
|
|
|
// Helper method to check if an EKU is present in a std::vector of EKUs. |
|
bool HasEKU(const std::vector<der::Input>& list, const der::Input& eku) { |
|
for (const auto& oid : list) { |
|
if (oid == eku) |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
// Check that we can read multiple EKUs from an extension. |
|
TEST(ExtendedKeyUsageTest, ParseEKUExtension) { |
|
// clang-format off |
|
const uint8_t raw_extension_value[] = { |
|
0x30, 0x14, // SEQUENCE (20 bytes) |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, // 1.3.6.1.5.5.7.3.1 |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02 // 1.3.6.1.5.5.7.3.2 |
|
// end of SEQUENCE |
|
}; |
|
// clang-format on |
|
der::Input extension_value(raw_extension_value); |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_TRUE(ParseEKUExtension(extension_value, &ekus)); |
|
|
|
EXPECT_EQ(2u, ekus.size()); |
|
EXPECT_TRUE(HasEKU(ekus, der::Input(kServerAuth))); |
|
EXPECT_TRUE(HasEKU(ekus, der::Input(kClientAuth))); |
|
} |
|
|
|
// Check that an extension with the same OID present multiple times doesn't |
|
// cause an error. |
|
TEST(ExtendedKeyUsageTest, RepeatedOid) { |
|
// clang-format off |
|
const uint8_t extension_bytes[] = { |
|
0x30, 0x14, // SEQUENCE (20 bytes) |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, // 1.3.6.1.5.5.7.3.1 |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01 // 1.3.6.1.5.5.7.3.1 |
|
}; |
|
// clang-format on |
|
der::Input extension(extension_bytes); |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_TRUE(ParseEKUExtension(extension, &ekus)); |
|
EXPECT_EQ(2u, ekus.size()); |
|
for (const auto& eku : ekus) { |
|
EXPECT_EQ(der::Input(kServerAuth), eku); |
|
} |
|
} |
|
|
|
// Check that parsing an EKU extension which contains a private OID doesn't |
|
// cause an error. |
|
TEST(ExtendedKeyUsageTest, ParseEKUExtensionGracefullyHandlesPrivateOids) { |
|
// clang-format off |
|
const uint8_t extension_bytes[] = { |
|
0x30, 0x13, // SEQUENCE (19 bytes) |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, // 1.3.6.1.5.5.7.3.1 |
|
0x06, 0x07, // OBJECT IDENTIFIER (7 bytes) |
|
0x2B, 0x06, 0x01, 0x04, 0x01, 0xD6, 0x79 // 1.3.6.1.4.1.11129 |
|
}; |
|
// clang-format on |
|
der::Input extension(extension_bytes); |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_TRUE(ParseEKUExtension(extension, &ekus)); |
|
EXPECT_EQ(2u, ekus.size()); |
|
EXPECT_TRUE(HasEKU(ekus, der::Input(kServerAuth))); |
|
|
|
const uint8_t google_oid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0xD6, 0x79}; |
|
der::Input google(google_oid); |
|
EXPECT_TRUE(HasEKU(ekus, google)); |
|
} |
|
|
|
// Test a variety of bad inputs. |
|
|
|
// If the extension value has data following the sequence of oids, parsing it |
|
// should fail. |
|
TEST(ExtendedKeyUsageTest, ExtraData) { |
|
// clang-format off |
|
const uint8_t extra_data[] = { |
|
0x30, 0x14, // SEQUENCE (20 bytes) |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, // 1.3.6.1.5.5.7.3.1 |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, // 1.3.6.1.5.5.7.3.2 |
|
// end of SEQUENCE |
|
0x02, 0x01, // INTEGER (1 byte) |
|
0x01 // 1 |
|
}; |
|
// clang-format on |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_FALSE(ParseEKUExtension(der::Input(extra_data), &ekus)); |
|
} |
|
|
|
// Check that ParseEKUExtension only accepts a sequence containing only oids. |
|
// This test case has an integer in the sequence (which should fail). A key |
|
// difference between this test case and ExtendedKeyUsageTest.ExtraData is where |
|
// the sequence ends - in this test case the integer is still part of the |
|
// sequence, while in ExtendedKeyUsageTest.ExtraData the integer is after the |
|
// sequence. |
|
TEST(ExtendedKeyUsageTest, NotAnOid) { |
|
// clang-format off |
|
const uint8_t not_an_oid[] = { |
|
0x30, 0x0d, // SEQUENCE (13 bytes) |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, // 1.3.6.1.5.5.7.3.1 |
|
0x02, 0x01, // INTEGER (1 byte) |
|
0x01 // 1 |
|
// end of SEQUENCE |
|
}; |
|
// clang-format on |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_FALSE(ParseEKUExtension(der::Input(not_an_oid), &ekus)); |
|
} |
|
|
|
// Checks that the list of oids passed to ParseEKUExtension are in a sequence, |
|
// instead of one or more oid tag-length-values concatenated together. |
|
TEST(ExtendedKeyUsageTest, NotASequence) { |
|
// clang-format off |
|
const uint8_t not_a_sequence[] = { |
|
0x06, 0x08, // OBJECT IDENTIFIER (8 bytes) |
|
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01 // 1.3.6.1.5.5.7.3.1 |
|
}; |
|
// clang-format on |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_FALSE(ParseEKUExtension(der::Input(not_a_sequence), &ekus)); |
|
} |
|
|
|
// A sequence passed into ParseEKUExtension must have at least one oid in it. |
|
TEST(ExtendedKeyUsageTest, EmptySequence) { |
|
const uint8_t empty_sequence[] = {0x30, 0x00}; // SEQUENCE (0 bytes) |
|
|
|
std::vector<der::Input> ekus; |
|
EXPECT_FALSE(ParseEKUExtension(der::Input(empty_sequence), &ekus)); |
|
} |
|
|
|
// The extension value must not be empty. |
|
TEST(ExtendedKeyUsageTest, EmptyExtension) { |
|
std::vector<der::Input> ekus; |
|
EXPECT_FALSE(ParseEKUExtension(der::Input(), &ekus)); |
|
} |
|
|
|
} // namespace |
|
|
|
} // namespace net
|
|
|