chromium/third_party/boringssl/src/crypto/x509/x509_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 <algorithm>
#include <functional>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bytestring.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/nid.h>
#include <openssl/pem.h>
#include <openssl/pool.h>
#include <openssl/x509.h>

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

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


static const char kCrossSigningRootPEM[] =;

static const char kRootCAPEM[] =;

static const char kRootCrossSignedPEM[] =;

static const char kIntermediatePEM[] =;

static const char kIntermediateSelfSignedPEM[] =;

static const char kLeafPEM[] =;

static const char kLeafNoKeyUsagePEM[] =;

static const char kForgeryPEM[] =;

// kBadPSSCertPEM is a self-signed RSA-PSS certificate with bad parameters.
static const char kBadPSSCertPEM[] =;

static const char kRSAKey[] =;

static const char kP256Key[] =;

// kCRLTestRoot is a test root certificate. It has private key:
//
//     -----BEGIN RSA PRIVATE KEY-----
//     MIIEpAIBAAKCAQEAo16WiLWZuaymsD8n5SKPmxV1y6jjgr3BS/dUBpbrzd1aeFzN
//     lI8l2jfAnzUyp+I21RQ+nh/MhqjGElkTtK9xMn1Y+S9GMRh+5R/Du0iCb1tCZIPY
//     07Tgrb0KMNWe0v2QKVVruuYSgxIWodBfxlKO64Z8AJ5IbnWpuRqO6rctN9qUoMlT
//     IAB6dL4G0tDJ/PGFWOJYwOMEIX54bly2wgyYJVBKiRRt4f7n8H922qmvPNA9idmX
//     9G1VAtgV6x97XXi7ULORIQvn9lVQF6nTYDBJhyuPB+mLThbLP2o9orxGx7aCtnnB
//     ZUIxUvHNOI0FaSaZH7Fi0xsZ/GkG2HZe7ImPJwIDAQABAoIBAQCJF9MTHfHGkk+/
//     DwCXlA0Wg0e6hBuHl10iNobYkMWIl/xXjOknhYiqOqb181py76472SVC5ERprC+r
//     Lf0PXzqKuA117mnkwT2bYLCL9Skf8WEhoFLQNbVlloF6wYjqXcYgKYKh8HgQbZl4
//     aLg2YQl2NADTNABsUWj/4H2WEelsODVviqfFs725lFg9KHDI8zxAZXLzDt/M9uVL
//     GxJiX12tr0AwaeAFZ1oPM/y+LznM3N3+Ht3jHHw3jZ/u8Z1RdAmdpu3bZ6tbwGBr
//     9edsH5rKkm9aBvMrY7eX5VHqaqyRNFyG152ZOJh4XiiFG7EmgTPCpaHo50Y018Re
//     grVtk+FBAoGBANY3lY+V8ZOwMxSHes+kTnoimHO5Ob7nxrOC71i27x+4HHsYUeAr
//     /zOOghiDIn+oNkuiX5CIOWZKx159Bp65CPpCbTb/fh+HYnSgXFgCw7XptycO7LXM
//     5GwR5jSfpfzBFdYxjxoUzDMFBwTEYRTm0HkUHkH+s+ajjw5wqqbcGLcfAoGBAMM8
//     DKW6Tb66xsf708f0jonAjKYTLZ+WOcwsBEWSFHoY8dUjvW5gqx5acHTEsc5ZTeh4
//     BCFLa+Mn9cuJWVJNs09k7Xb2PNl92HQ4GN2vbdkJhExbkT6oLDHg1hVD0w8KLfz1
//     lTAW6pS+6CdOHMEJpvqx89EgU/1GgIQ1fXYczE75AoGAKeJoXdDFkUjsU+FBhAPu
//     TDcjc80Nm2QaF9NMFR5/lsYa236f06MGnQAKM9zADBHJu/Qdl1brUjLg1HrBppsr
//     RDNkw1IlSOjhuUf5hkPUHGd8Jijm440SRIcjabqla8wdBupdvo2+d2NOQgJbsQiI
//     ToQ+fkzcxAXK3Nnuo/1436UCgYBjLH7UNOZHS8OsVM0I1r8NVKVdu4JCfeJQR8/H
//     s2P5ffBir+wLRMnH+nMDreMQiibcPxMCArkERAlE4jlgaJ38Z62E76KLbLTmnJRt
//     EC9Bv+bXjvAiHvWMRMUbOj/ddPNVez7Uld+FvdBaHwDWQlvzHzBWfBCOKSEhh7Z6
//     qDhUqQKBgQDPMDx2i5rfmQp3imV9xUcCkIRsyYQVf8Eo7NV07IdUy/otmksgn4Zt
//     Lbf3v2dvxOpTNTONWjp2c+iUQo8QxJCZr5Sfb21oQ9Ktcrmc/CY7LeBVDibXwxdM
//     vRG8kBzvslFWh7REzC3u06GSVhyKDfW93kN2cKVwGoahRlhj7oHuZQ==
//     -----END RSA PRIVATE KEY-----
static const char kCRLTestRoot[] =;

static const char kCRLTestLeaf[] =;

static const char kBasicCRL[] =;

static const char kRevokedCRL[] =;

static const char kBadIssuerCRL[] =;

// kKnownCriticalCRL is kBasicCRL but with a critical issuing distribution point
// extension.
static const char kKnownCriticalCRL[] =;

// kUnknownCriticalCRL is kBasicCRL but with an unknown critical extension.
static const char kUnknownCriticalCRL[] =;

// kUnknownCriticalCRL2 is kBasicCRL but with a critical issuing distribution
// point extension followed by an unknown critical extension
static const char kUnknownCriticalCRL2[] =;

// kBadExtensionCRL is kBasicCRL but with an incorrectly-encoded issuing
// distribution point extension.
static const char kBadExtensionCRL[] =;

// kAlgorithmMismatchCRL is kBasicCRL but with mismatched AlgorithmIdentifiers
// in the outer structure and signed portion. The signature reflects the signed
// portion.
static const char kAlgorithmMismatchCRL[] =;

// kAlgorithmMismatchCRL2 is kBasicCRL but with mismatched AlgorithmIdentifiers
// in the outer structure and signed portion. The signature reflects the outer
// structure.
static const char kAlgorithmMismatchCRL2[] =;

// kEd25519Cert is a self-signed Ed25519 certificate.
static const char kEd25519Cert[] =;

// kEd25519CertNull is an invalid self-signed Ed25519 with an explicit NULL in
// the signature algorithm.
static const char kEd25519CertNull[] =;

// kX25519 is the example X25519 certificate from
// https://tools.ietf.org/html/rfc8410#section-10.2
static const char kX25519Cert[] =;

// kSANTypesLeaf is a leaf certificate (signed by |kSANTypesRoot|) which
// contains SANS for example.com, [email protected], 127.0.0.1, and
// https://example.com/. (The latter is useless for now since crypto/x509
// doesn't deal with URI SANs directly.)
static const char kSANTypesLeaf[] =;

// -----BEGIN RSA PRIVATE KEY-----
// MIICWwIBAAKBgQDbRn2TLhInBki8Bighq37EtqJd/h5SRYh6NkelCA2SQlvCgcC+
// l3mYQPtPbRT9KxOLwqUuZ9jUCZ7WIji3Sgt0cyvCNPHRk+WW2XR781ifbGE8wLBB
// 1NkrKyQjd1scO711Xc4gVM+hY4cdHiTE8x0aUIuqthRD7ZendWL0FMhS1wIDAQAB
// AoGACwf7z0i1DxOI2zSwFimLghfyCSp8mgT3fbZ3Wj0SebYu6ZUffjceneM/AVrq
// gGYHYLOVHcWJqfkl7X3hPo9SDhzLx0mM545/q21ZWCwjhswH7WiCEqV2/zeDO9WU
// NIO1VU0VoLm0AQ7ZvwnyB+fpgF9kkkDtbBJW7XWrfNVtlnECQQD97YENpEJ3X1kj
// 3rrkrHWDkKAyoWWY1i8Fm7LnganC9Bv6AVwgn5ZlE/479aWHF8vbOFEA3pFPiNZJ
// t9FTCfpJAkEA3RCXjGI0Y6GALFLwEs+nL/XZAfJaIpJEZVLCVosYQOSaMS4SchfC
// GGYVquT7ZgKk9uvz89Fg87OtBMWS9lrkHwJADGkGLKeBhBoJ3kHtem2fVK3F1pOi
// xoR5SdnhNYVVyaxqjZ5xZTrHe+stOrr3uxGDqhQniVZXXb6/Ul0Egv1y2QJAVg/h
// kAujba4wIhFf2VLyOZ+yjil1ocPj0LZ5Zgvcs1bMGJ1hHP3W2HzVrqRaowoggui1
// HpTC891dXGA2qKYV7QJAFDmT2A7OVvh3y4AEgzVwHrDmCMwMHKjCIntS7fjxrJnF
// YvJUG1zoHwUVrxxbR3DbpTODlktLcl/0b97D0IkH3w==
// -----END RSA PRIVATE KEY-----

static const char kSANTypesRoot[] =;

// -----BEGIN RSA PRIVATE KEY-----
// MIICXAIBAAKBgQDpDn8RDOZa5oaDcPZRBy4CeBH1siSSOO4mYgLHlPE+oXdqwI/V
// Imi2XeJM2uCFETXCknJJjYG0iJdrt/yyRFvZTQZw+QzGj+mz36NqhGxDWb6dstB2
// m8PX+plZw7jl81MDvUnWs8yiQ/6twgu5AbhWKZQDJKcNKCEpqa6UW0r5nwIDAQAB
// AoGALEF5daZqc+aEsp8X1yky3nsoheyPL0kqSBWii33IFemZgKcSaRnAoqjPWWLS
// 8dHj0I/4rej2MW8iuezVSpDak9tK5boHORC3w4p/wifkizQkLt1DANxTVbzcKvrt
// aZ7LjVaKkhjRJbLddniowFHkkWVbUccjvzcUd7Y2VuLbAhECQQDq4FE88aHio8zg
// bxSd0PwjEFwLYQTR19u812SoR8PmR6ofIL+pDwOV+fVs+OGcAAOgkhIukOrksQ4A
// 1cKtnyhXAkEA/gRI+u3tZ7UE1twIkBfZ6IvCdRodkPqHAYIxMRLzL+MhyZt4MEGc
// Ngb/F6U9/WOBFnoR/PI7IwE3ejutzKcL+QJBAKh+6eilk7QKPETZi1m3/dmNt+p1
// 3EZJ65pqjwxmB3Rg/vs7vCMk4TarTdSyKu+F1xRPFfoP/mK3Xctdjj6NyhsCQAYF
// 7/0TOzfkUPMPUJyqFB6xgbDpJ55ScnUUsznoqx+NkTWInDb4t02IqO/UmT2y6FKy
// Hk8TJ1fTJY+ebqaVp3ECQApx9gQ+n0zIhx97FMUuiRse73xkcW4+pZ8nF+8DmeQL
// /JKuuFGmzkG+rUbXFmo/Zg2ozVplw71NnQJ4znPsf7A=
// -----END RSA PRIVATE KEY-----

// The following four certificates were generated with this Go program, varying
// |includeNetscapeExtension| and defining rootKeyPEM and rootCertPEM to be
// strings containing the kSANTypesRoot, above.

// package main

// import (
//     "crypto/ecdsa"
//     "crypto/elliptic"
//     "crypto/rand"
//     "crypto/x509"
//     "crypto/x509/pkix"
//     "encoding/asn1"
//     "encoding/pem"
//     "math/big"
//     "os"
//     "time"
// )

// const includeNetscapeExtension = true

// func main() {
//     block, _ := pem.Decode([]byte(rootKeyPEM))
//     rootPriv, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
//     block, _ = pem.Decode([]byte(rootCertPEM))
//     root, _ := x509.ParseCertificate(block.Bytes)

//     interTemplate := &x509.Certificate{
//         SerialNumber: big.NewInt(2),
//         Subject: pkix.Name{
//             CommonName: "No Basic Constraints (Netscape)",
//         },
//         NotBefore: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
//         NotAfter:  time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC),
//     }

//     if includeNetscapeExtension {
//         interTemplate.ExtraExtensions = []pkix.Extension{
//             pkix.Extension{
//                 Id:    asn1.ObjectIdentifier([]int{2, 16, 840, 1, 113730, 1, 1}),
//                 Value: []byte{0x03, 0x02, 2, 0x04},
//             },
//         }
//     } else {
//         interTemplate.KeyUsage = x509.KeyUsageCertSign
//     }

//     interKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

//     interDER, err := x509.CreateCertificate(rand.Reader, interTemplate, root, &interKey.PublicKey, rootPriv)
//     if err != nil {
//         panic(err)
//     }

//     pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: interDER})

//     inter, _ := x509.ParseCertificate(interDER)

//     leafTemplate := &x509.Certificate{
//         SerialNumber: big.NewInt(3),
//         Subject: pkix.Name{
//             CommonName: "Leaf from CA with no Basic Constraints",
//         },
//         NotBefore:             time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
//         NotAfter:              time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC),
//         BasicConstraintsValid: true,
//     }
//     leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

//     leafDER, err := x509.CreateCertificate(rand.Reader, leafTemplate, inter, &leafKey.PublicKey, interKey)
//     if err != nil {
//         panic(err)
//     }

//     pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
// }

// kNoBasicConstraintsCertSignIntermediate doesn't have isCA set, but contains
// certSign in the keyUsage.
static const char kNoBasicConstraintsCertSignIntermediate[] =;

static const char kNoBasicConstraintsCertSignLeaf[] =;

// kNoBasicConstraintsNetscapeCAIntermediate doesn't have isCA set, but contains
// a Netscape certificate-type extension that asserts a type of "SSL CA".
static const char kNoBasicConstraintsNetscapeCAIntermediate[] =;

static const char kNoBasicConstraintsNetscapeCALeaf[] =;

static const char kSelfSignedMismatchAlgorithms[] =;

// kCommonNameWithSANs is a leaf certificate signed by kSANTypesRoot, with
// *.host1.test as the common name and a SAN list of *.host2.test and
// foo.host3.test.
static const char kCommonNameWithSANs[] =;

// kCommonNameWithSANs is a leaf certificate signed by kSANTypesRoot, with
// *.host1.test as the common name and no SAN list.
static const char kCommonNameWithoutSANs[] =;

// kCommonNameWithEmailSAN is a leaf certificate signed by kSANTypesRoot, with
// *.host1.test as the common name and the email address [email protected] in the
// SAN list.
static const char kCommonNameWithEmailSAN[] =;

// kCommonNameWithIPSAN is a leaf certificate signed by kSANTypesRoot, with
// *.host1.test as the common name and the IP address 127.0.0.1 in the
// SAN list.
static const char kCommonNameWithIPSAN[] =;

// kConstrainedIntermediate is an intermediate signed by kSANTypesRoot, with
// permitted DNS names of permitted1.test and foo.permitted2.test and an
// excluded DNS name of excluded.permitted1.test. Its private key is:
//
// -----BEGIN PRIVATE KEY-----
// MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTXUM4tJWM7OzATty
// JhNOfIv/d8heWFBeKOfMR+RfaROhRANCAASbbbWYiN6mn+BCpg4XNpibOH0D/DN4
// kZ5C/Ml2YVomC9T83OKk2CzB8fPAabPb4P4Vv+fIabpEfjWS5nzKLY1y
// -----END PRIVATE KEY-----
static const char kConstrainedIntermediate[] =;

// kCommonNamePermittedLeaf is a leaf certificate signed by
// kConstrainedIntermediate. Its common name is permitted by the name
// constraints.
static const char kCommonNamePermittedLeaf[] =;
static const char kCommonNamePermitted[] =;

// kCommonNameNotPermittedLeaf is a leaf certificate signed by
// kConstrainedIntermediate. Its common name is not permitted by the name
// constraints.
static const char kCommonNameNotPermittedLeaf[] =;
static const char kCommonNameNotPermitted[] =;

// kCommonNameNotPermittedWithSANsLeaf is a leaf certificate signed by
// kConstrainedIntermediate. Its common name is not permitted by the name
// constraints but it has a SAN list.
static const char kCommonNameNotPermittedWithSANsLeaf[] =;
static const char kCommonNameNotPermittedWithSANs[] =;

// kCommonNameNotDNSLeaf is a leaf certificate signed by
// kConstrainedIntermediate. Its common name is not a DNS name.
static const char kCommonNameNotDNSLeaf[] =;
static const char kCommonNameNotDNS[] =;

// The following six certificates are issued by |kSANTypesRoot| and have
// different extended key usage values. They were created with the following
// Go program:
//
// func main() {
//     block, _ := pem.Decode([]byte(rootKeyPEM))
//     rootPriv, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
//     block, _ = pem.Decode([]byte(rootCertPEM))
//     root, _ := x509.ParseCertificate(block.Bytes)
//
//     leafTemplate := &x509.Certificate{
//         SerialNumber: big.NewInt(3),
//         Subject: pkix.Name{
//             CommonName: "EKU msSGC",
//         },
//         NotBefore:             time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
//         NotAfter:              time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC),
//         BasicConstraintsValid: true,
//         ExtKeyUsage:           []x509.ExtKeyUsage{FILL IN HERE},
//     }
//     leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
//     leafDER, err := x509.CreateCertificate(rand.Reader, leafTemplate, root, &leafKey.PublicKey, rootPriv)
//     if err != nil {
//         panic(err)
//     }
//     pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
// }

static const char kMicrosoftSGCCert[] =;

static const char kNetscapeSGCCert[] =;

static const char kServerEKUCert[] =;

static const char kServerEKUPlusMicrosoftSGCCert[] =;

static const char kAnyEKU[] =;

static const char kNoEKU[] =;

// CertFromPEM parses the given, NUL-terminated PEM block and returns an
// |X509*|.
static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {}

// CRLFromPEM parses the given, NUL-terminated PEM block and returns an
// |X509_CRL*|.
static bssl::UniquePtr<X509_CRL> CRLFromPEM(const char *pem) {}

// CSRFromPEM parses the given, NUL-terminated PEM block and returns an
// |X509_REQ*|.
static bssl::UniquePtr<X509_REQ> CSRFromPEM(const char *pem) {}

// PrivateKeyFromPEM parses the given, NUL-terminated PEM block and returns an
// |EVP_PKEY*|.
static bssl::UniquePtr<EVP_PKEY> PrivateKeyFromPEM(const char *pem) {}

// CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509),
// bumping the reference counts for each certificate in question.
static bssl::UniquePtr<STACK_OF(X509)> CertsToStack(
    const std::vector<X509 *> &certs) {}

// CRLsToStack converts a vector of |X509_CRL*| to an OpenSSL
// STACK_OF(X509_CRL), bumping the reference counts for each CRL in question.
static bssl::UniquePtr<STACK_OF(X509_CRL)> CRLsToStack(
    const std::vector<X509_CRL *> &crls) {}

static const int64_t kReferenceTime = /* Sep 27th, 2016 */;

static int Verify(
    X509 *leaf, const std::vector<X509 *> &roots,
    const std::vector<X509 *> &intermediates,
    const std::vector<X509_CRL *> &crls, unsigned long flags = 0,
    std::function<void(X509_STORE_CTX *)> configure_callback = nullptr) {}

TEST(X509Test, TestVerify) {}

#if defined(OPENSSL_THREADS)
// Verifying the same |X509| objects on two threads should be safe.
TEST(X509Test, VerifyThreads) {}

// Using the same CRL on two threads should be safe.
TEST(X509Test, CRLThreads) {}

TEST(X509Test, StoreThreads) {}
#endif  // OPENSSL_THREADS

static const char kHostname[] =;
static const char kWrongHostname[] =;
static const char kEmail[] =;
static const char kWrongEmail[] =;
static const uint8_t kIP[4] =;
static const uint8_t kWrongIP[4] =;
static const char kIPString[] =;
static const char kWrongIPString[] =;

TEST(X509Test, ZeroLengthsWithX509PARAM) {}

TEST(X509Test, ZeroLengthsWithCheckFunctions) {}

TEST(X509Test, TestCRL) {}

TEST(X509Test, ManyNamesAndConstraints) {}

static bssl::UniquePtr<GENERAL_NAME> MakeGeneralName(int type,
                                                     const std::string &value) {}

static bssl::UniquePtr<X509_NAME> MakeTestName(const char *common_name) {}

static bssl::UniquePtr<X509> MakeTestCert(const char *issuer,
                                          const char *subject, EVP_PKEY *key,
                                          bool is_ca) {}

static bool AddExtendedKeyUsage(X509 *x509, const std::vector<int> &eku_nids) {}

enum class KeyUsage : int {};

static bool AddKeyUsage(X509 *x509, const std::vector<KeyUsage> usages) {}

static bool AddSubjectKeyIdentifier(X509 *x509,
                                    bssl::Span<const uint8_t> key_id) {}

static bool AddAuthorityKeyIdentifier(X509 *x509,
                                      bssl::Span<const uint8_t> key_id) {}

static bssl::UniquePtr<X509_CRL> MakeTestCRL(const char *issuer,
                                             int this_update_offset_day,
                                             int next_update_offset_day) {}

static bool AddRevokedSerialU64(X509_CRL *crl, uint64_t serial,
                                int offset_day) {}

static bool AddAuthorityKeyIdentifier(X509_CRL *crl,
                                     bssl::Span<const uint8_t> key_id) {}

TEST(X509Test, NameConstraints) {}

TEST(X509Test, PrintGeneralName) {}

TEST(X509Test, TestPSS) {}

TEST(X509Test, TestPSSBadParameters) {}

TEST(X509Test, TestEd25519) {}

TEST(X509Test, TestEd25519BadParameters) {}

TEST(X509Test, TestX25519) {}

static bssl::UniquePtr<X509> ReencodeCertificate(X509 *cert) {}

static bssl::UniquePtr<X509_CRL> ReencodeCRL(X509_CRL *crl) {}

static bssl::UniquePtr<X509_REQ> ReencodeCSR(X509_REQ *req) {}

static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {}

TEST(X509Test, RSASign) {}

// Test the APIs for signing a certificate, particularly whether they correctly
// handle the TBSCertificate cache.
TEST(X509Test, SignCertificate) {}

// Test the APIs for signing a CRL, particularly whether they correctly handle
// the TBSCertList cache.
TEST(X509Test, SignCRL) {}

static const char kTestCSR[] =;

// Test the APIs for signing a CSR, particularly whether they correctly handle
// the CertificationRequestInfo cache.
TEST(X509Test, SignCSR) {}

TEST(X509Test, Ed25519Sign) {}

static bool PEMToDER(bssl::UniquePtr<uint8_t> *out, size_t *out_len,
                     const char *pem) {}

TEST(X509Test, TestFromBuffer) {}

TEST(X509Test, TestFromBufferWithTrailingData) {}

TEST(X509Test, TestFromBufferModified) {}

TEST(X509Test, TestFromBufferReused) {}

TEST(X509Test, TestFailedParseFromBuffer) {}

TEST(X509Test, TestPrintUTCTIME) {}

TEST(X509Test, PrettyPrintIntegers) {}

TEST(X509Test, X509AlgorSetMd) {}

TEST(X509Test, X509NameSet) {}

// Tests that |X509_NAME_hash| and |X509_NAME_hash_old|'s values never change.
// These functions figure into |X509_LOOKUP_hash_dir|'s on-disk format, so they
// must remain stable. In particular, if we ever remove name canonicalization,
// we'll need to preserve it for |X509_NAME_hash|.
TEST(X509Test, NameHash) {}

TEST(X509Test, NoBasicConstraintsCertSign) {}

TEST(X509Test, NoBasicConstraintsNetscapeCA) {}

TEST(X509Test, MismatchAlgorithms) {}

TEST(X509Test, PEMX509Info) {}

TEST(X509Test, ReadBIOEmpty) {}

TEST(X509Test, ReadBIOOneByte) {}

TEST(X509Test, PartialBIOReturn) {}

TEST(X509Test, CommonNameFallback) {}

TEST(X509Test, LooksLikeDNSName) {}

TEST(X509Test, CommonNameAndNameConstraints) {}

TEST(X509Test, ServerGatedCryptoEKUs) {}

// Test that invalid extensions are rejected by, if not the parser, at least the
// verifier.
TEST(X509Test, InvalidExtensions) {}

// kExplicitDefaultVersionPEM is an X.509v1 certificate with the version number
// encoded explicitly, rather than omitted as required by DER.
static const char kExplicitDefaultVersionPEM[] =;

// kNegativeVersionPEM is an X.509 certificate with a negative version number.
static const char kNegativeVersionPEM[] =;

// kFutureVersionPEM is an X.509 certificate with a version number value of
// three, which is not defined. (v3 has value two).
static const char kFutureVersionPEM[] =;

// kOverflowVersionPEM is an X.509 certificate with a version field which
// overflows |uint64_t|.
static const char kOverflowVersionPEM[] =;

// kV1WithExtensionsPEM is an X.509v1 certificate with extensions.
static const char kV1WithExtensionsPEM[] =;

// kV2WithExtensionsPEM is an X.509v2 certificate with extensions.
static const char kV2WithExtensionsPEM[] =;

// kV1WithIssuerUniqueIDPEM is an X.509v1 certificate with an issuerUniqueID.
static const char kV1WithIssuerUniqueIDPEM[] =;

// kV1WithSubjectUniqueIDPEM is an X.509v1 certificate with an issuerUniqueID.
static const char kV1WithSubjectUniqueIDPEM[] =;

// kV1CRLWithExtensionsPEM is a v1 CRL with extensions.
static const char kV1CRLWithExtensionsPEM[] =;

// kExplicitDefaultVersionCRLPEM is a v1 CRL with an explicitly-encoded version
// field.
static const char kExplicitDefaultVersionCRLPEM[] =;

// kV3CRLPEM is a v3 CRL. CRL versions only go up to v2.
static const char kV3CRLPEM[] =;

// kV2CSRPEM is a v2 CSR. CSR versions only go up to v1.
static const char kV2CSRPEM[] =;

// kV3CSRPEM is a v3 CSR. CSR versions only go up to v1.
static const char kV3CSRPEM[] =;

// Test that the library enforces versions are valid and match the fields
// present.
TEST(X509Test, InvalidVersion) {}

// Unlike upstream OpenSSL, we require a non-null store in
// |X509_STORE_CTX_init|.
TEST(X509Test, NullStore) {}

TEST(X509Test, StoreCtxReuse) {}

TEST(X509Test, BasicConstraints) {}

// The following strings are test certificates signed by kP256Key and kRSAKey,
// with missing, NULL, or invalid algorithm parameters.
static const char kP256NoParam[] =;
static const char kP256NullParam[] =;
static const char kP256InvalidParam[] =;
static const char kRSANoParam[] =;
static const char kRSANullParam[] =;
static const char kRSAInvalidParam[] =;

TEST(X509Test, AlgorithmParameters) {}

TEST(X509Test, GeneralName)  {}

// Test that extracting fields of an |X509_ALGOR| works correctly.
TEST(X509Test, X509AlgorExtract) {}

// Test the various |X509_ATTRIBUTE| creation functions.
TEST(X509Test, Attribute) {}

// Test that, by default, |X509_V_FLAG_TRUSTED_FIRST| is set, which means we'll
// skip over server-sent expired intermediates when there is a local trust
// anchor that works better.
TEST(X509Test, TrustedFirst) {}

// Test that notBefore and notAfter checks work correctly.
TEST(X509Test, Expiry) {}

TEST(X509Test, SignatureVerification) {}

// kConstructedBitString is an X.509 certificate where the signature is encoded
// as a BER constructed BIT STRING. Note that, while OpenSSL's parser accepts
// this input, it interprets the value incorrectly.
static const char kConstructedBitString[] =;

// kConstructedOctetString is an X.509 certificate where an extension is encoded
// as a BER constructed OCTET STRING.
static const char kConstructedOctetString[] =;

// kIndefiniteLength is an X.509 certificate where the outermost SEQUENCE uses
// BER indefinite-length encoding.
static const char kIndefiniteLength[] =;

// kNonZeroPadding is an X.09 certificate where the BIT STRING signature field
// has non-zero padding values.
static const char kNonZeroPadding[] =;

// kHighTagNumber is an X.509 certificate where the outermost SEQUENCE tag uses
// high tag number form.
static const char kHighTagNumber[] =;

// kNonMinimalLengthOuter is an X.509 certificate where the outermost SEQUENCE
// has a non-minimal length.
static const char kNonMinimalLengthOuter[] =;

// kNonMinimalLengthSignature is an X.509 certificate where the signature has a
// non-minimal length.
static const char kNonMinimalLengthSignature[] =;

// kNonMinimalLengthSerial is an X.509 certificate where the serial number has a
// non-minimal length.
static const char kNonMinimalLengthSerial[] =;

TEST(X509Test, BER) {}

TEST(X509Test, Names) {}

TEST(X509Test, AddDuplicates) {}

TEST(X509Test, BytesToHex) {}

TEST(X509Test, NamePrint) {}

// kLargeSerialPEM is a certificate with a large serial number.
static const char kLargeSerialPEM[] =;

TEST(X509Test, Print) {}

TEST(X509Test, AddExt) {}

TEST(X509Test, NameEntry) {}

// Tests that non-integer types are rejected when passed as an argument to
// X509_set_serialNumber().
TEST(X509Test, SetSerialNumberChecksASN1StringType) {}

TEST(X509Test, Policy) {}

#if defined(OPENSSL_THREADS)
// A similar test to the above, but ensures the various bits of intermediate
// state are computed safely.
TEST(X509Test, PolicyThreads) {}
#endif  // OPENSSL_THREADS

TEST(X509Test, ExtensionFromConf) {}

TEST(X509Test, AddUnserializableExtension) {}

// Test that, when constructing an |X509_NAME|, names are sorted by DER order.
TEST(X509Test, SortRDN) {}

TEST(X509Test, NameAttributeValues) {}

TEST(X509Test, GetTextByOBJ) {}

TEST(X509Test, ParamInheritance) {}

TEST(X509Test, PublicKeyCache) {}

// Tests some unusual behavior in |X509_STORE_CTX_set_purpose| and
// |X509_STORE_CTX_set_trust|.
TEST(X509Test, ContextTrustAndPurpose) {}

TEST(X509Test, Purpose) {}

TEST(X509Test, Trust) {}

// Test some APIs that rust-openssl uses to look up purposes by name.
TEST(X509Test, PurposeByShortName) {}

TEST(X509Test, CriticalExtension) {}

enum NameHash {};

// TemporaryHashDir constructs a temporary directory in the format of
// |X509_LOOKUP_hash_dir|.
class TemporaryHashDir {};

// TODO(davidben): Also test CRL handling. There are some interesting behaviors
// in here.
TEST(X509Test, DirHash) {}

// Test that two directory hash paths are treated as a sequence of paths,
// separated by a separator.
TEST(X509Test, DirHashSeparator) {}

#if defined(OPENSSL_THREADS)
// Test that directory hash lookup is thread-safe.
TEST(X509Test, DirHashThreads) {}
#endif  // OPENSSL_THREADS

// Test that, when there are two CAs with the same name, but different key
// identifiers, certificate and CRL lookup can disambiguate correctly.
TEST(X509Test, DuplicateName) {}

TEST(X509Test, ParseIPAddress) {}