chromium/third_party/boringssl/src/crypto/asn1/asn1_test.cc

/* Copyright (c) 2016, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <limits.h>
#include <stdio.h>

#include <map>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bio.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/pem.h>
#include <openssl/posix_time.h>
#include <openssl/span.h>
#include <openssl/x509.h>

#include "../test/test_util.h"
#include "internal.h"

#if defined(OPENSSL_THREADS)
#include <thread>
#endif


// |obj| and |i2d_func| require different template parameters because C++ may
// deduce, say, |ASN1_STRING*| via |obj| and |const ASN1_STRING*| via
// |i2d_func|. Template argument deduction then fails. The language is not able
// to resolve this by observing that |const ASN1_STRING*| works for both.
template <typename T, typename U>
void TestSerialize(T obj, int (*i2d_func)(U a, uint8_t **pp),
                   bssl::Span<const uint8_t> expected) {}

// Historically, unknown universal tags were represented in |ASN1_TYPE| as
// |ASN1_STRING|s with the type matching the tag number. This can collide with
// |V_ASN_NEG|, which was one of the causes of CVE-2016-2108. We now represent
// unsupported values with |V_ASN1_OTHER|, but retain the |V_ASN1_MAX_UNIVERSAL|
// limit.
TEST(ASN1Test, UnknownTags) {}

static bssl::UniquePtr<BIGNUM> BIGNUMPow2(unsigned bit) {}

TEST(ASN1Test, Integer) {}

// Although invalid, a negative zero should encode correctly.
TEST(ASN1Test, NegativeZero) {}

TEST(ASN1Test, SerializeObject) {}

TEST(ASN1Test, Boolean) {}

// The templates go through a different codepath, so test them separately.
TEST(ASN1Test, SerializeEmbeddedBoolean) {}

TEST(ASN1Test, ASN1Type) {}

// Test that reading |value.ptr| from a FALSE |ASN1_TYPE| behaves correctly. The
// type historically supported this, so maintain the invariant in case external
// code relies on it.
TEST(ASN1Test, UnusedBooleanBits) {}

TEST(ASN1Test, ParseASN1Object) {}

TEST(ASN1Test, BitString) {}

TEST(ASN1Test, SetBit) {}

TEST(ASN1Test, StringToUTF8) {}

static std::string ASN1StringToStdString(const ASN1_STRING *str) {}

static bool ASN1Time_check_posix(const ASN1_TIME *s, int64_t t) {}

static std::string PrintStringToBIO(const ASN1_STRING *str,
                                    int (*print_func)(BIO *,
                                                      const ASN1_STRING *)) {}

TEST(ASN1Test, SetTime) {}

TEST(ASN1Test, TimeSetString) {}

TEST(ASN1Test, AdjTime) {}
static std::vector<uint8_t> StringToVector(const std::string &str) {}

TEST(ASN1Test, StringPrintEx) {}

TEST(ASN1Test, MBString) {}

TEST(ASN1Test, StringByNID) {}

TEST(ASN1Test, StringByCustomNID) {}

#if defined(OPENSSL_THREADS)
TEST(ASN1Test, StringByCustomNIDThreads) {}
#endif  // OPENSSL_THREADS

// Test that multi-string types correctly encode negative ENUMERATED.
// Multi-string types cannot contain INTEGER, so we only test ENUMERATED.
TEST(ASN1Test, NegativeEnumeratedMultistring) {}

// Encoding a CHOICE type with an invalid selector should fail.
TEST(ASN1Test, InvalidChoice) {}

// Encoding NID-only |ASN1_OBJECT|s should fail.
TEST(ASN1Test, InvalidObject) {}

// Encoding invalid |ASN1_TYPE|s should fail. |ASN1_TYPE|s are
// default-initialized to an invalid type.
TEST(ASN1Test, InvalidASN1Type) {}

// Encoding invalid MSTRING types should fail. An MSTRING is a CHOICE of
// string-like types. They are initialized to an invalid type.
TEST(ASN1Test, InvalidMSTRING) {}

TEST(ASN1Test, StringTableSorted) {}

TEST(ASN1Test, Null) {}

TEST(ASN1Test, Pack) {}

TEST(ASN1Test, Unpack) {}

TEST(ASN1Test, StringCmp) {}

TEST(ASN1Test, PrintASN1Object) {}

TEST(ASN1Test, GetObject) {}

template <typename T>
void ExpectNoParse(T *(*d2i)(T **, const uint8_t **, long),
                   const std::vector<uint8_t> &in) {}

// The zero tag, constructed or primitive, is reserved and should rejected by
// the parser.
TEST(ASN1Test, ZeroTag) {}

TEST(ASN1Test, StringEncoding) {}

// Exhaustively test POSIX time conversions for every day across the millenium.
TEST(ASN1Test, POSIXTime) {}

TEST(ASN1Test, LargeString) {}

static auto TimeToTuple(const tm &t) {}

TEST(ASN1Test, TimeOverflow) {}

// The ASN.1 macros do not work on Windows shared library builds, where usage of
// |OPENSSL_EXPORT| is a bit stricter.
#if !defined(OPENSSL_WINDOWS) || !defined(BORINGSSL_SHARED_LIBRARY)

ASN1_LINKED_LIST;

DECLARE_ASN1_ITEM(ASN1_LINKED_LIST)
DECLARE_ASN1_FUNCTIONS(ASN1_LINKED_LIST)

ASN1_SEQUENCE(ASN1_LINKED_LIST) = ASN1_SEQUENCE_END(ASN1_LINKED_LIST)

IMPLEMENT_ASN1_FUNCTIONS()

static bool MakeLinkedList(bssl::UniquePtr<uint8_t> *out, size_t *out_len,
                           size_t count) {}

TEST(ASN1Test, Recursive) {}

struct IMPLICIT_CHOICE {};

DECLARE_ASN1_FUNCTIONS(IMPLICIT_CHOICE)

ASN1_SEQUENCE(IMPLICIT_CHOICE) = ASN1_SEQUENCE_END(IMPLICIT_CHOICE)

IMPLEMENT_ASN1_FUNCTIONS()

// Test that the ASN.1 templates reject types with implicitly-tagged CHOICE
// types.
TEST(ASN1Test, ImplicitChoice) {}

struct REQUIRED_FIELD {};

DECLARE_ASN1_FUNCTIONS(REQUIRED_FIELD)
ASN1_SEQUENCE(REQUIRED_FIELD) = ASN1_SEQUENCE_END(REQUIRED_FIELD)
IMPLEMENT_ASN1_FUNCTIONS()

// Test that structures with missing required fields cannot be serialized. Test
// the full combination of tagging and SEQUENCE OF.
TEST(ASN1Test, MissingRequiredField) {}

struct BOOLEANS {};

DECLARE_ASN1_FUNCTIONS(BOOLEANS)
ASN1_SEQUENCE(BOOLEANS) = ASN1_SEQUENCE_END(BOOLEANS)
IMPLEMENT_ASN1_FUNCTIONS()

TEST(ASN1Test, OptionalAndDefaultBooleans) {}

// EXPLICIT_BOOLEAN is a [1] EXPLICIT BOOLEAN.
ASN1_ITEM_TEMPLATE(EXPLICIT_BOOLEAN) =
ASN1_ITEM_TEMPLATE_END(EXPLICIT_BOOLEAN)

// EXPLICIT_OCTET_STRING is a [2] EXPLICIT OCTET STRING.
ASN1_ITEM_TEMPLATE(EXPLICIT_OCTET_STRING) =
ASN1_ITEM_TEMPLATE_END(EXPLICIT_OCTET_STRING)

// DOUBLY_TAGGED is
//   SEQUENCE {
//     b   [3] EXPLICIT [1] EXPLICIT BOOLEAN OPTIONAL,
//     oct [4] EXPLICIT [2] EXPLICIT OCTET STRING OPTIONAL }
// with explicit tagging.
struct DOUBLY_TAGGED {};

DECLARE_ASN1_FUNCTIONS(DOUBLY_TAGGED)
ASN1_SEQUENCE(DOUBLY_TAGGED) = ASN1_SEQUENCE_END(DOUBLY_TAGGED)
IMPLEMENT_ASN1_FUNCTIONS()

// Test that optional fields with two layers of explicit tagging are correctly
// handled.
TEST(ASN1Test, DoublyTagged) {}

#define CHOICE_TYPE_OCT
#define CHOICE_TYPE_BOOL

struct CHOICE_TYPE {};

DECLARE_ASN1_FUNCTIONS(CHOICE_TYPE)
ASN1_CHOICE(CHOICE_TYPE) = ASN1_CHOICE_END()
IMPLEMENT_ASN1_FUNCTIONS()

struct OPTIONAL_CHOICE {};

DECLARE_ASN1_FUNCTIONS(OPTIONAL_CHOICE)
ASN1_SEQUENCE(OPTIONAL_CHOICE) = ASN1_SEQUENCE_END(OPTIONAL_CHOICE)
IMPLEMENT_ASN1_FUNCTIONS()

TEST(ASN1Test, OptionalChoice) {}

struct EMBED_X509_ALGOR {};

struct EMBED_X509_EXTENSION {};

struct EMBED_X509_NAME {};

struct EMBED_X509 {};

DECLARE_ASN1_FUNCTIONS(EMBED_X509_ALGOR)
ASN1_SEQUENCE(EMBED_X509_ALGOR) = ASN1_SEQUENCE_END(EMBED_X509_ALGOR)
IMPLEMENT_ASN1_FUNCTIONS()

DECLARE_ASN1_FUNCTIONS(EMBED_X509_NAME)
ASN1_SEQUENCE(EMBED_X509_NAME) = ASN1_SEQUENCE_END(EMBED_X509_NAME)
IMPLEMENT_ASN1_FUNCTIONS()

DECLARE_ASN1_FUNCTIONS(EMBED_X509_EXTENSION)
ASN1_SEQUENCE(EMBED_X509_EXTENSION) = ASN1_SEQUENCE_END(EMBED_X509_EXTENSION)
IMPLEMENT_ASN1_FUNCTIONS()

DECLARE_ASN1_FUNCTIONS(EMBED_X509)
ASN1_SEQUENCE(EMBED_X509) = ASN1_SEQUENCE_END(EMBED_X509)
IMPLEMENT_ASN1_FUNCTIONS()

template <typename EmbedT, typename T, typename MaybeConstT, typename StackT>
void TestEmbedType(bssl::Span<const uint8_t> inp,
                   int (*i2d)(MaybeConstT *, uint8_t **),
                   EmbedT *(*embed_new)(), void (*embed_free)(EmbedT *),
                   EmbedT *(*d2i_embed)(EmbedT **, const uint8_t **, long),
                   int (*i2d_embed)(EmbedT *, uint8_t **),
                   size_t (*sk_num)(const StackT *),
                   T *(*sk_value)(const StackT *, size_t)) {}

// Test that X.509 types defined in this library can be embedded into other
// types, as we rewrite them away from the templating system.
TEST(ASN1Test, EmbedTypes) {}

#endif  // !WINDOWS || !SHARED_LIBRARY