blob: f5578466c75797ab87dea2764e8c614005dce177 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/web_package/signed_exchange_certificate_chain.h"
#include "base/optional.h"
#include "base/strings/string_piece.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
base::Optional<std::vector<base::StringPiece>> GetCertChain(
const uint8_t* input,
size_t input_size) {
return SignedExchangeCertificateChain::GetCertChainFromMessage(
base::make_span(input, input_size));
}
} // namespace
TEST(SignedExchangeCertificateParseTest, OneCert) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x00, 0x07, // certificate list size
0x00, 0x00, 0x02, // cert data size
0x11, 0x22, // cert data
0x00, 0x00, // extensions size
// clang-format on
};
base::Optional<std::vector<base::StringPiece>> certs =
GetCertChain(input, arraysize(input));
ASSERT_TRUE(certs);
ASSERT_EQ(1u, certs->size());
const uint8_t kExpected[] = {
// clang-format off
0x11, 0x22, // cert data
// clang-format on
};
EXPECT_THAT((*certs)[0],
testing::ElementsAreArray(kExpected, arraysize(kExpected)));
}
TEST(SignedExchangeCertificateParseTest, OneCertWithExtension) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x00, 0x0A, // certificate list size
0x00, 0x00, 0x02, // cert data size
0x11, 0x22, // cert data
0x00, 0x03, // extensions size
0xE1, 0xE2, 0xE3, // extensions data
// clang-format on
};
base::Optional<std::vector<base::StringPiece>> certs =
GetCertChain(input, arraysize(input));
ASSERT_TRUE(certs);
ASSERT_EQ(1u, certs->size());
const uint8_t kExpected[] = {
// clang-format off
0x11, 0x22, // cert data
// clang-format on
};
EXPECT_THAT((*certs)[0],
testing::ElementsAreArray(kExpected, arraysize(kExpected)));
}
TEST(SignedExchangeCertificateParseTest, TwoCerts) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x01, 0x13, // certificate list size
0x00, 0x01, 0x04, // cert data size
// cert data
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x00, // extensions size
0x00, 0x00, 0x05, // cert data size
0x33, 0x44, 0x55, 0x66, 0x77, // cert data
0x00, 0x00, // extensions size
// clang-format on
};
const uint8_t kExpected1[] = {
// clang-format off
// cert data
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
// clang-format on
};
const uint8_t kExpected2[] = {
// clang-format off
0x33, 0x44, 0x55, 0x66, 0x77, // cert data
// clang-format on
};
base::Optional<std::vector<base::StringPiece>> certs =
GetCertChain(input, sizeof(input));
ASSERT_TRUE(certs);
ASSERT_EQ(2u, certs->size());
EXPECT_THAT((*certs)[0],
testing::ElementsAreArray(kExpected1, arraysize(kExpected1)));
EXPECT_THAT((*certs)[1],
testing::ElementsAreArray(kExpected2, arraysize(kExpected2)));
}
TEST(SignedExchangeCertificateParseTest, Empty) {
EXPECT_FALSE(GetCertChain(nullptr, 0));
}
TEST(SignedExchangeCertificateParseTest, InvalidRequestContextSize) {
const uint8_t input[] = {
// clang-format off
0x01, // request context size: must be zero
0x20, // request context
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, CanNotReadCertListSize1) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x01, // certificate list size: must be 3 bytes
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, CanNotReadCertListSize2) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x01, // certificate list size: must be 3 bytes
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, CertListSizeError) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x01, 0x01, // certificate list size: 257 (This must be 7)
0x00, 0x00, 0x02, // cert data size
0x11, 0x22, // cert data
0x00, 0x00, // extensions size
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, CanNotReadCertDataSize) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x00, 0x02, // certificate list size
0x00, 0x01, // cert data size: must be 3 bytes
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, CertDataSizeError) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x00, 0x04, // certificate list size
0x00, 0x00, 0x02, // cert data size
0x11, // cert data: Need 2 bytes
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, CanNotReadExtensionsSize) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x00, 0x06, // certificate list size
0x00, 0x00, 0x02, // cert data size
0x11, 0x22, // cert data
0x00, // extensions size : must be 2 bytes
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
TEST(SignedExchangeCertificateParseTest, ExtensionsSizeError) {
const uint8_t input[] = {
// clang-format off
0x00, // request context size
0x00, 0x00, 0x07, // certificate list size
0x00, 0x00, 0x02, // cert data size
0x11, 0x22, // cert data
0x00, 0x01, // extensions size
// clang-format on
};
EXPECT_FALSE(GetCertChain(input, arraysize(input)));
}
} // namespace content