external/boringssl: Sync to 5e578c9dba73460c3eb17f771c77fc8e36f7812e.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/58e449904e248f34bdfc2be7a609c58bcb0257b7..5e578c9dba73460c3eb17f771c77fc8e36f7812e

Test: BoringSSL CTS Presubmits
Change-Id: Ic1541b034545fa58a284ca35134b3719303455c7
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 0d8c98c..74001e7 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -39,7 +39,6 @@
   x509name.c
   x509rset.c
   x509spki.c
-  x509type.c
   x_algor.c
   x_all.c
   x_attrib.c
@@ -56,14 +55,3 @@
   x_x509.c
   x_x509a.c
 )
-
-add_executable(
-  x509_test
-
-  x509_test.cc
-
-  $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(x509_test crypto)
-add_dependencies(all_tests x509_test)
diff --git a/src/crypto/x509/a_sign.c b/src/crypto/x509/a_sign.c
index 13a3ac2..b3ea1de 100644
--- a/src/crypto/x509/a_sign.c
+++ b/src/crypto/x509/a_sign.c
@@ -104,8 +104,7 @@
         goto err;
     }
 
-    if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
-        || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+    if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) {
         outl = 0;
         OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
         goto err;
diff --git a/src/crypto/x509/a_verify.c b/src/crypto/x509/a_verify.c
index 400cdd1..d203fba 100644
--- a/src/crypto/x509/a_verify.c
+++ b/src/crypto/x509/a_verify.c
@@ -73,6 +73,7 @@
 int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
                      ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
 {
+    EVP_MD_CTX ctx;
     uint8_t *buf_in = NULL;
     int ret = 0, inl = 0;
 
@@ -86,9 +87,9 @@
         return 0;
     }
 
-    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
-    if (ctx == NULL ||
-        !x509_digest_verify_init(ctx, a)) {
+    EVP_MD_CTX_init(&ctx);
+
+    if (!x509_digest_verify_init(&ctx, a, pkey)) {
         goto err;
     }
 
@@ -99,19 +100,19 @@
         goto err;
     }
 
-    if (!EVP_PKEY_verify_message(ctx, signature->data,
-                                 (size_t)signature->length, buf_in, inl)) {
+    if (!EVP_DigestVerify(&ctx, signature->data, (size_t)signature->length,
+                          buf_in, inl)) {
         OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
         goto err;
     }
 
     ret = 1;
 
- err:
+err:
     if (buf_in != NULL) {
-        OPENSSL_cleanse(buf_in, (unsigned int)inl);
+        OPENSSL_cleanse(buf_in, inl);
         OPENSSL_free(buf_in);
     }
-    EVP_PKEY_CTX_free(ctx);
+    EVP_MD_CTX_cleanup(&ctx);
     return ret;
 }
diff --git a/src/crypto/x509/algorithm.c b/src/crypto/x509/algorithm.c
index 6e0f3f2..8f53fff 100644
--- a/src/crypto/x509/algorithm.c
+++ b/src/crypto/x509/algorithm.c
@@ -66,9 +66,8 @@
 
 
 int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
-  const EVP_MD *digest = EVP_MD_CTX_md(ctx);
   EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
-  if (digest == NULL || pkey == NULL) {
+  if (pkey == NULL) {
     OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
     return 0;
   }
@@ -84,8 +83,18 @@
     }
   }
 
+  if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) {
+    return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
+  }
+
   /* Default behavior: look up the OID for the algorithm/hash pair and encode
    * that. */
+  const EVP_MD *digest = EVP_MD_CTX_md(ctx);
+  if (digest == NULL) {
+    OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
+    return 0;
+  }
+
   int sign_nid;
   if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest),
                               EVP_PKEY_id(pkey))) {
@@ -101,11 +110,8 @@
   return 1;
 }
 
-int x509_digest_verify_init(EVP_PKEY_CTX *ctx, X509_ALGOR *sigalg) {
-  if (!EVP_PKEY_verify_init(ctx)) {
-    return 0;
-  }
-
+int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
+                            EVP_PKEY *pkey) {
   /* Convert the signature OID into digest and public key OIDs. */
   int sigalg_nid = OBJ_obj2nid(sigalg->algorithm);
   int digest_nid, pkey_nid;
@@ -115,7 +121,6 @@
   }
 
   /* Check the public key OID matches the public key type. */
-  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
   if (pkey_nid != EVP_PKEY_id(pkey)) {
     OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
     return 0;
@@ -124,14 +129,14 @@
   /* NID_undef signals that there are custom parameters to set. */
   if (digest_nid == NID_undef) {
     if (sigalg_nid == NID_rsassaPss) {
-      return x509_rsa_pss_to_ctx(ctx, sigalg);
+      return x509_rsa_pss_to_ctx(ctx, sigalg, pkey);
     }
-    if (sigalg_nid == NID_Ed25519) {
+    if (sigalg_nid == NID_ED25519) {
       if (sigalg->parameter != NULL) {
         OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER);
         return 0;
       }
-      return 1; /* Nothing to configure. */
+      return EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey);
     }
     OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
     return 0;
@@ -144,5 +149,5 @@
     return 0;
   }
 
-  return EVP_PKEY_CTX_set_signature_md(ctx, digest);
+  return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey);
 }
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index e68ca5a..d72f9ec 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -84,8 +84,8 @@
     STACK_OF(BY_DIR_ENTRY) *dirs;
 } BY_DIR;
 
-DECLARE_STACK_OF(BY_DIR_HASH)
-DECLARE_STACK_OF(BY_DIR_ENTRY)
+DEFINE_STACK_OF(BY_DIR_HASH)
+DEFINE_STACK_OF(BY_DIR_ENTRY)
 
 static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
                     char **ret);
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index ebeb72e..2bec572 100644
--- a/src/crypto/x509/by_file.c
+++ b/src/crypto/x509/by_file.c
@@ -89,12 +89,12 @@
                         long argl, char **ret)
 {
     int ok = 0;
-    char *file;
+    const char *file;
 
     switch (cmd) {
     case X509_L_FILE_LOAD:
         if (argl == X509_FILETYPE_DEFAULT) {
-            file = (char *)getenv(X509_get_default_cert_file_env());
+            file = getenv(X509_get_default_cert_file_env());
             if (file)
                 ok = (X509_load_cert_crl_file(ctx, file,
                                               X509_FILETYPE_PEM) != 0);
diff --git a/src/crypto/x509/internal.h b/src/crypto/x509/internal.h
index f7101af..4957c1e 100644
--- a/src/crypto/x509/internal.h
+++ b/src/crypto/x509/internal.h
@@ -28,8 +28,9 @@
 
 /* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on
  * signature algorithm parameters in |sigalg| (which must have type
- * |NID_rsassaPss|). It returns one on success and zero on error. */
-int x509_rsa_pss_to_ctx(EVP_PKEY_CTX *ctx, X509_ALGOR *sigalg);
+ * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on
+ * error. */
+int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey);
 
 /* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for
  * |ctx|, which must have been configured for an RSA-PSS signing operation. It
@@ -51,9 +52,11 @@
 int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor);
 
 /* x509_digest_verify_init sets up |ctx| for a signature verification operation
- * with parameters from |algor|. The |ctx| argument must have been constructed
- * with the public key. It returns one on success, or zero on error. */
-int x509_digest_verify_init(EVP_PKEY_CTX *ctx, X509_ALGOR *sigalg);
+ * with public key |pkey| and parameters from |algor|. The |ctx| argument must
+ * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or
+ * zero on error. */
+int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
+                            EVP_PKEY *pkey);
 
 
 #if defined(__cplusplus)
diff --git a/src/crypto/x509/rsa_pss.c b/src/crypto/x509/rsa_pss.c
index 9c286c6..9230934 100644
--- a/src/crypto/x509/rsa_pss.c
+++ b/src/crypto/x509/rsa_pss.c
@@ -242,7 +242,7 @@
   return ret;
 }
 
-int x509_rsa_pss_to_ctx(EVP_PKEY_CTX *ctx, X509_ALGOR *sigalg) {
+int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
   assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
 
   /* Decode PSS parameters */
@@ -279,10 +279,11 @@
     goto err;
   }
 
-  if (!EVP_PKEY_CTX_set_signature_md(ctx, md) ||
-      !EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) ||
-      !EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen) ||
-      !EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1md)) {
+  EVP_PKEY_CTX *pctx;
+  if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) ||
+      !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+      !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) ||
+      !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) {
     goto err;
   }
 
diff --git a/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
index 6e23cb8..1b34578 100644
--- a/src/crypto/x509/x509_test.cc
+++ b/src/crypto/x509/x509_test.cc
@@ -12,13 +12,14 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
 
+#include <string>
 #include <vector>
 
-#include <assert.h>
-#include <string.h>
+#include <gtest/gtest.h>
 
 #include <openssl/bio.h>
 #include <openssl/bytestring.h>
+#include <openssl/curve25519.h>
 #include <openssl/crypto.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
@@ -553,7 +554,7 @@
   return r1;
 }
 
-static bool TestVerify() {
+TEST(X509Test, TestVerify) {
   bssl::UniquePtr<X509> cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
   bssl::UniquePtr<X509> root(CertFromPEM(kRootCAPEM));
   bssl::UniquePtr<X509> root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
@@ -564,94 +565,53 @@
   bssl::UniquePtr<X509> leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
   bssl::UniquePtr<X509> forgery(CertFromPEM(kForgeryPEM));
 
-  if (!cross_signing_root ||
-      !root ||
-      !root_cross_signed ||
-      !intermediate ||
-      !intermediate_self_signed ||
-      !leaf ||
-      !leaf_no_key_usage ||
-      !forgery) {
-    fprintf(stderr, "Failed to parse certificates\n");
-    return false;
-  }
+  ASSERT_TRUE(cross_signing_root);
+  ASSERT_TRUE(root);
+  ASSERT_TRUE(root_cross_signed);
+  ASSERT_TRUE(intermediate);
+  ASSERT_TRUE(intermediate_self_signed);
+  ASSERT_TRUE(leaf);
+  ASSERT_TRUE(forgery);
+  ASSERT_TRUE(leaf_no_key_usage);
 
   std::vector<X509*> empty;
   std::vector<X509_CRL*> empty_crls;
-  if (Verify(leaf.get(), empty, empty, empty_crls) !=
-      X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
-    fprintf(stderr, "Leaf verified with no roots!\n");
-    return false;
-  }
+  ASSERT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+            Verify(leaf.get(), empty, empty, empty_crls));
+  ASSERT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+            Verify(leaf.get(), empty, {intermediate.get()}, empty_crls));
 
-  if (Verify(leaf.get(), empty, {intermediate.get()}, empty_crls) !=
-      X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
-    fprintf(stderr, "Leaf verified with no roots!\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()}, {intermediate.get()}, empty_crls) !=
-      X509_V_OK) {
-    ERR_print_errors_fp(stderr);
-    fprintf(stderr, "Basic chain didn't verify.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {cross_signing_root.get()},
-             {intermediate.get(), root_cross_signed.get()},
-             empty_crls) != X509_V_OK) {
-    ERR_print_errors_fp(stderr);
-    fprintf(stderr, "Cross-signed chain didn't verify.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {cross_signing_root.get(), root.get()},
-             {intermediate.get(), root_cross_signed.get()},
-             empty_crls) != X509_V_OK) {
-    ERR_print_errors_fp(stderr);
-    fprintf(stderr, "Cross-signed chain with root didn't verify.\n");
-    return false;
-  }
+  ASSERT_EQ(X509_V_OK,
+            Verify(leaf.get(), {root.get()}, {intermediate.get()}, empty_crls));
+  ASSERT_EQ(X509_V_OK,
+            Verify(leaf.get(), {cross_signing_root.get()},
+                   {intermediate.get(), root_cross_signed.get()}, empty_crls));
+  ASSERT_EQ(X509_V_OK,
+            Verify(leaf.get(), {cross_signing_root.get(), root.get()},
+                   {intermediate.get(), root_cross_signed.get()}, empty_crls));
 
   /* This is the “altchains” test – we remove the cross-signing CA but include
    * the cross-sign in the intermediates. */
-  if (Verify(leaf.get(), {root.get()},
-             {intermediate.get(), root_cross_signed.get()},
-             empty_crls) != X509_V_OK) {
-    ERR_print_errors_fp(stderr);
-    fprintf(stderr, "Chain with cross-sign didn't backtrack to find root.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()},
-             {intermediate.get(), root_cross_signed.get()}, empty_crls,
-             X509_V_FLAG_NO_ALT_CHAINS) !=
-      X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
-    fprintf(stderr, "Altchains test still passed when disabled.\n");
-    return false;
-  }
-
-  if (Verify(forgery.get(), {intermediate_self_signed.get()},
-             {leaf_no_key_usage.get()},
-             empty_crls) != X509_V_ERR_INVALID_CA) {
-    fprintf(stderr, "Basic constraints weren't checked.\n");
-    return false;
-  }
+  ASSERT_EQ(X509_V_OK,
+            Verify(leaf.get(), {root.get()},
+                   {intermediate.get(), root_cross_signed.get()}, empty_crls));
+  ASSERT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+            Verify(leaf.get(), {root.get()},
+                   {intermediate.get(), root_cross_signed.get()}, empty_crls,
+                   X509_V_FLAG_NO_ALT_CHAINS));
+  ASSERT_EQ(X509_V_ERR_INVALID_CA,
+            Verify(forgery.get(), {intermediate_self_signed.get()},
+                   {leaf_no_key_usage.get()}, empty_crls));
 
   /* Test that one cannot skip Basic Constraints checking with a contorted set
    * of roots and intermediates. This is a regression test for CVE-2015-1793. */
-  if (Verify(forgery.get(),
-             {intermediate_self_signed.get(), root_cross_signed.get()},
-             {leaf_no_key_usage.get(), intermediate.get()},
-             empty_crls) != X509_V_ERR_INVALID_CA) {
-    fprintf(stderr, "Basic constraints weren't checked.\n");
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(X509_V_ERR_INVALID_CA,
+            Verify(forgery.get(),
+                   {intermediate_self_signed.get(), root_cross_signed.get()},
+                   {leaf_no_key_usage.get(), intermediate.get()}, empty_crls));
 }
 
-static bool TestCRL() {
+TEST(X509Test, TestCRL) {
   bssl::UniquePtr<X509> root(CertFromPEM(kCRLTestRoot));
   bssl::UniquePtr<X509> leaf(CertFromPEM(kCRLTestLeaf));
   bssl::UniquePtr<X509_CRL> basic_crl(CRLFromPEM(kBasicCRL));
@@ -663,145 +623,84 @@
   bssl::UniquePtr<X509_CRL> unknown_critical_crl2(
       CRLFromPEM(kUnknownCriticalCRL2));
 
-  if (!root ||
-      !leaf ||
-      !basic_crl ||
-      !revoked_crl ||
-      !bad_issuer_crl ||
-      !known_critical_crl ||
-      !unknown_critical_crl ||
-      !unknown_critical_crl2) {
-    fprintf(stderr, "Failed to parse certificates and CRLs.\n");
-    return false;
-  }
+  ASSERT_TRUE(root);
+  ASSERT_TRUE(leaf);
+  ASSERT_TRUE(basic_crl);
+  ASSERT_TRUE(revoked_crl);
+  ASSERT_TRUE(bad_issuer_crl);
+  ASSERT_TRUE(known_critical_crl);
+  ASSERT_TRUE(unknown_critical_crl);
+  ASSERT_TRUE(unknown_critical_crl2);
 
-  if (Verify(leaf.get(), {root.get()}, {root.get()}, {basic_crl.get()},
-             X509_V_FLAG_CRL_CHECK) != X509_V_OK) {
-    fprintf(stderr, "Cert with CRL didn't verify.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()}, {root.get()},
-             {basic_crl.get(), revoked_crl.get()},
-             X509_V_FLAG_CRL_CHECK) != X509_V_ERR_CERT_REVOKED) {
-    fprintf(stderr, "Revoked CRL wasn't checked.\n");
-    return false;
-  }
+  ASSERT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {root.get()},
+                              {basic_crl.get()}, X509_V_FLAG_CRL_CHECK));
+  ASSERT_EQ(
+      X509_V_ERR_CERT_REVOKED,
+      Verify(leaf.get(), {root.get()}, {root.get()},
+             {basic_crl.get(), revoked_crl.get()}, X509_V_FLAG_CRL_CHECK));
 
   std::vector<X509_CRL *> empty_crls;
-  if (Verify(leaf.get(), {root.get()}, {root.get()}, empty_crls,
-             X509_V_FLAG_CRL_CHECK) != X509_V_ERR_UNABLE_TO_GET_CRL) {
-    fprintf(stderr, "CRLs were not required.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()}, {root.get()}, {bad_issuer_crl.get()},
-             X509_V_FLAG_CRL_CHECK) != X509_V_ERR_UNABLE_TO_GET_CRL) {
-    fprintf(stderr, "Bad CRL issuer was unnoticed.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()}, {root.get()}, {known_critical_crl.get()},
-             X509_V_FLAG_CRL_CHECK) != X509_V_OK) {
-    fprintf(stderr, "CRL with known critical extension was rejected.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()}, {root.get()},
-             {unknown_critical_crl.get()}, X509_V_FLAG_CRL_CHECK) !=
-      X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION) {
-    fprintf(stderr, "CRL with unknown critical extension was accepted.\n");
-    return false;
-  }
-
-  if (Verify(leaf.get(), {root.get()}, {root.get()},
-             {unknown_critical_crl2.get()}, X509_V_FLAG_CRL_CHECK) !=
-      X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION) {
-    fprintf(stderr, "CRL with unknown critical extension (2) was accepted.\n");
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(X509_V_ERR_UNABLE_TO_GET_CRL,
+            Verify(leaf.get(), {root.get()}, {root.get()}, empty_crls,
+                   X509_V_FLAG_CRL_CHECK));
+  ASSERT_EQ(X509_V_ERR_UNABLE_TO_GET_CRL,
+            Verify(leaf.get(), {root.get()}, {root.get()},
+                   {bad_issuer_crl.get()}, X509_V_FLAG_CRL_CHECK));
+  ASSERT_EQ(X509_V_OK,
+            Verify(leaf.get(), {root.get()}, {root.get()},
+                   {known_critical_crl.get()}, X509_V_FLAG_CRL_CHECK));
+  ASSERT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION,
+            Verify(leaf.get(), {root.get()}, {root.get()},
+                   {unknown_critical_crl.get()}, X509_V_FLAG_CRL_CHECK));
+  ASSERT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION,
+            Verify(leaf.get(), {root.get()}, {root.get()},
+                   {unknown_critical_crl2.get()}, X509_V_FLAG_CRL_CHECK));
 }
 
-static bool TestPSS() {
+TEST(X509Test, TestPSS) {
   bssl::UniquePtr<X509> cert(CertFromPEM(kExamplePSSCert));
-  if (!cert) {
-    return false;
-  }
+  ASSERT_TRUE(cert);
 
   bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
-  if (!pkey) {
-    return false;
-  }
+  ASSERT_TRUE(pkey);
 
-  if (!X509_verify(cert.get(), pkey.get())) {
-    fprintf(stderr, "Could not verify certificate.\n");
-    return false;
-  }
-  return true;
+  ASSERT_TRUE(X509_verify(cert.get(), pkey.get()));
 }
 
-static bool TestBadPSSParameters() {
+TEST(X509Test, TestPSSBadParameters) {
   bssl::UniquePtr<X509> cert(CertFromPEM(kBadPSSCertPEM));
-  if (!cert) {
-    return false;
-  }
+  ASSERT_TRUE(cert);
 
   bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
-  if (!pkey) {
-    return false;
-  }
+  ASSERT_TRUE(pkey);
 
-  if (X509_verify(cert.get(), pkey.get())) {
-    fprintf(stderr, "Unexpectedly verified bad certificate.\n");
-    return false;
-  }
+  ASSERT_FALSE(X509_verify(cert.get(), pkey.get()));
   ERR_clear_error();
-  return true;
 }
 
-static bool TestEd25519() {
+TEST(X509Test, TestEd25519) {
   bssl::UniquePtr<X509> cert(CertFromPEM(kEd25519Cert));
-  if (!cert) {
-    return false;
-  }
+  ASSERT_TRUE(cert);
 
   bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
-  if (!pkey) {
-    return false;
-  }
+  ASSERT_TRUE(pkey);
 
-  if (!X509_verify(cert.get(), pkey.get())) {
-    fprintf(stderr, "Could not verify certificate.\n");
-    return false;
-  }
-  return true;
+  ASSERT_TRUE(X509_verify(cert.get(), pkey.get()));
 }
 
-static bool TestBadEd25519Parameters() {
+TEST(X509Test, TestEd25519BadParameters) {
   bssl::UniquePtr<X509> cert(CertFromPEM(kEd25519CertNull));
-  if (!cert) {
-    return false;
-  }
+  ASSERT_TRUE(cert);
 
   bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
-  if (!pkey) {
-    return false;
-  }
+  ASSERT_TRUE(pkey);
 
-  if (X509_verify(cert.get(), pkey.get())) {
-    fprintf(stderr, "Unexpectedly verified bad certificate.\n");
-    return false;
-  }
+  ASSERT_FALSE(X509_verify(cert.get(), pkey.get()));
+
   uint32_t err = ERR_get_error();
-  if (ERR_GET_LIB(err) != ERR_LIB_X509 ||
-      ERR_GET_REASON(err) != X509_R_INVALID_PARAMETER) {
-    fprintf(stderr, "Did not get X509_R_INVALID_PARAMETER as expected.\n");
-    return false;
-  }
+  ASSERT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
+  ASSERT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
   ERR_clear_error();
-  return true;
 }
 
 static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
@@ -816,33 +715,38 @@
   return !!X509_verify(cert.get(), pkey);
 }
 
-static bool TestSignCtx() {
+TEST(X509Test, RSASign) {
   bssl::UniquePtr<EVP_PKEY> pkey(PrivateKeyFromPEM(kRSAKey));
-  if (!pkey) {
-    return false;
-  }
-
+  ASSERT_TRUE(pkey);
   // Test PKCS#1 v1.5.
   bssl::ScopedEVP_MD_CTX md_ctx;
-  if (!EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
-      !SignatureRoundTrips(md_ctx.get(), pkey.get())) {
-    fprintf(stderr, "RSA PKCS#1 with SHA-256 failed\n");
-    return false;
-  }
+  ASSERT_TRUE(
+      EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()));
+  ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pkey.get()));
 
   // Test RSA-PSS with custom parameters.
   md_ctx.Reset();
   EVP_PKEY_CTX *pkey_ctx;
-  if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
-                          pkey.get()) ||
-      !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
-      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
-      !SignatureRoundTrips(md_ctx.get(), pkey.get())) {
-    fprintf(stderr, "RSA-PSS failed\n");
-    return false;
-  }
+  ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
+                                 pkey.get()));
+  ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING));
+  ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()));
+  ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pkey.get()));
+}
 
-  return true;
+TEST(X509Test, Ed25519Sign) {
+  uint8_t pub_bytes[32], priv_bytes[64];
+  ED25519_keypair(pub_bytes, priv_bytes);
+
+  bssl::UniquePtr<EVP_PKEY> pub(EVP_PKEY_new_ed25519_public(pub_bytes));
+  ASSERT_TRUE(pub);
+  bssl::UniquePtr<EVP_PKEY> priv(EVP_PKEY_new_ed25519_private(priv_bytes));
+  ASSERT_TRUE(priv);
+
+  bssl::ScopedEVP_MD_CTX md_ctx;
+  ASSERT_TRUE(
+      EVP_DigestSignInit(md_ctx.get(), nullptr, nullptr, nullptr, priv.get()));
+  ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pub.get()));
 }
 
 static bool PEMToDER(bssl::UniquePtr<uint8_t> *out, size_t *out_len,
@@ -868,149 +772,89 @@
   return true;
 }
 
-static bool TestFromBuffer() {
+TEST(X509Test, TestFromBuffer) {
   size_t data_len;
   bssl::UniquePtr<uint8_t> data;
-  if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data, &data_len, kRootCAPEM));
 
   bssl::UniquePtr<CRYPTO_BUFFER> buf(
       CRYPTO_BUFFER_new(data.get(), data_len, nullptr));
-  if (!buf) {
-    return false;
-  }
-
+  ASSERT_TRUE(buf);
   bssl::UniquePtr<X509> root(X509_parse_from_buffer(buf.get()));
-  if (!root) {
-    return false;
-  }
+  ASSERT_TRUE(root);
 
   const uint8_t *enc_pointer = root->cert_info->enc.enc;
   const uint8_t *buf_pointer = CRYPTO_BUFFER_data(buf.get());
-  if (enc_pointer < buf_pointer ||
-      enc_pointer >= buf_pointer + CRYPTO_BUFFER_len(buf.get())) {
-    fprintf(stderr, "TestFromBuffer: enc does not alias the buffer.\n");
-    return false;
-  }
-
+  ASSERT_GE(enc_pointer, buf_pointer);
+  ASSERT_LT(enc_pointer, buf_pointer + CRYPTO_BUFFER_len(buf.get()));
   buf.reset();
 
   /* This ensures the X509 took a reference to |buf|, otherwise this will be a
    * reference to free memory and ASAN should notice. */
-  if (enc_pointer[0] != CBS_ASN1_SEQUENCE) {
-    fprintf(stderr, "TestFromBuffer: enc data is not a SEQUENCE.\n");
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(CBS_ASN1_SEQUENCE, enc_pointer[0]);
 }
 
-static bool TestFromBufferTrailingData() {
+TEST(X509Test, TestFromBufferWithTrailingData) {
   size_t data_len;
   bssl::UniquePtr<uint8_t> data;
-  if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data, &data_len, kRootCAPEM));
 
   std::unique_ptr<uint8_t[]> trailing_data(new uint8_t[data_len + 1]);
   OPENSSL_memcpy(trailing_data.get(), data.get(), data_len);
 
   bssl::UniquePtr<CRYPTO_BUFFER> buf_trailing_data(
       CRYPTO_BUFFER_new(trailing_data.get(), data_len + 1, nullptr));
-  if (!buf_trailing_data) {
-    return false;
-  }
+  ASSERT_TRUE(buf_trailing_data);
 
   bssl::UniquePtr<X509> root_trailing_data(
       X509_parse_from_buffer(buf_trailing_data.get()));
-  if (root_trailing_data) {
-    fprintf(stderr, "TestFromBuffer: trailing data was not rejected.\n");
-    return false;
-  }
-
-  return true;
+  ASSERT_FALSE(root_trailing_data);
 }
 
-static bool TestFromBufferModified() {
+TEST(X509Test, TestFromBufferModified) {
   size_t data_len;
   bssl::UniquePtr<uint8_t> data;
-  if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data, &data_len, kRootCAPEM));
 
   bssl::UniquePtr<CRYPTO_BUFFER> buf(
       CRYPTO_BUFFER_new(data.get(), data_len, nullptr));
-  if (!buf) {
-    return false;
-  }
+  ASSERT_TRUE(buf);
 
   bssl::UniquePtr<X509> root(X509_parse_from_buffer(buf.get()));
-  if (!root) {
-    return false;
-  }
+  ASSERT_TRUE(root);
 
   bssl::UniquePtr<ASN1_INTEGER> fourty_two(ASN1_INTEGER_new());
   ASN1_INTEGER_set(fourty_two.get(), 42);
   X509_set_serialNumber(root.get(), fourty_two.get());
 
-  if (i2d_X509(root.get(), nullptr) != static_cast<long>(data_len)) {
-    fprintf(stderr,
-            "TestFromBufferModified: i2d_X509 gives different answer before "
-            "marking as modified.\n");
-    return false;
-  }
+  ASSERT_EQ(static_cast<long>(data_len), i2d_X509(root.get(), nullptr));
 
   X509_CINF_set_modified(root->cert_info);
 
-  if (i2d_X509(root.get(), nullptr) == static_cast<long>(data_len)) {
-    fprintf(stderr,
-            "TestFromBufferModified: i2d_X509 gives same answer after marking "
-            "as modified.\n");
-    return false;
-  }
-
-  return true;
+  ASSERT_NE(static_cast<long>(data_len), i2d_X509(root.get(), nullptr));
 }
 
-static bool TestFromBufferReused() {
+TEST(X509Test, TestFromBufferReused) {
   size_t data_len;
   bssl::UniquePtr<uint8_t> data;
-  if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data, &data_len, kRootCAPEM));
 
   bssl::UniquePtr<CRYPTO_BUFFER> buf(
       CRYPTO_BUFFER_new(data.get(), data_len, nullptr));
-  if (!buf) {
-    return false;
-  }
+  ASSERT_TRUE(buf);
 
   bssl::UniquePtr<X509> root(X509_parse_from_buffer(buf.get()));
-  if (!root) {
-    return false;
-  }
+  ASSERT_TRUE(root);
 
   size_t data2_len;
   bssl::UniquePtr<uint8_t> data2;
-  if (!PEMToDER(&data2, &data2_len, kLeafPEM)) {
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data2, &data2_len, kLeafPEM));
 
   X509 *x509p = root.get();
   const uint8_t *inp = data2.get();
   X509 *ret = d2i_X509(&x509p, &inp, data2_len);
-  if (ret != root.get()) {
-    fprintf(stderr,
-            "TestFromBufferReused: d2i_X509 parsed into a different object.\n");
-    return false;
-  }
-
-  if (root->buf != nullptr) {
-    fprintf(stderr,
-            "TestFromBufferReused: d2i_X509 didn't clear |buf| pointer.\n");
-    return false;
-  }
+  ASSERT_EQ(root.get(), ret);
+  ASSERT_EQ(nullptr, root->buf);
 
   // Free |data2| and ensure that |root| took its own copy. Otherwise the
   // following will trigger a use-after-free.
@@ -1018,50 +862,31 @@
 
   uint8_t *i2d = nullptr;
   int i2d_len = i2d_X509(root.get(), &i2d);
-  if (i2d_len < 0) {
-    return false;
-  }
+  ASSERT_GE(i2d_len, 0);
   bssl::UniquePtr<uint8_t> i2d_storage(i2d);
 
-  if (!PEMToDER(&data2, &data2_len, kLeafPEM)) {
-    return false;
-  }
-  if (i2d_len != static_cast<long>(data2_len) ||
-      OPENSSL_memcmp(data2.get(), i2d, i2d_len) != 0) {
-    fprintf(stderr, "TestFromBufferReused: i2d gave wrong result.\n");
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data2, &data2_len, kLeafPEM));
 
-  if (root->buf != NULL) {
-    fprintf(stderr, "TestFromBufferReused: X509.buf was not cleared.\n");
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(static_cast<long>(data2_len), i2d_len);
+  ASSERT_EQ(0, OPENSSL_memcmp(data2.get(), i2d, i2d_len));
+  ASSERT_EQ(nullptr, root->buf);
 }
 
-static bool TestFailedParseFromBuffer() {
+TEST(X509Test, TestFailedParseFromBuffer) {
   static const uint8_t kNonsense[] = {1, 2, 3, 4, 5};
 
   bssl::UniquePtr<CRYPTO_BUFFER> buf(
       CRYPTO_BUFFER_new(kNonsense, sizeof(kNonsense), nullptr));
-  if (!buf) {
-    return false;
-  }
+  ASSERT_TRUE(buf);
 
   bssl::UniquePtr<X509> cert(X509_parse_from_buffer(buf.get()));
-  if (cert) {
-    fprintf(stderr, "Nonsense somehow parsed.\n");
-    return false;
-  }
+  ASSERT_FALSE(cert);
   ERR_clear_error();
 
   // Test a buffer with trailing data.
   size_t data_len;
   bssl::UniquePtr<uint8_t> data;
-  if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
-    return false;
-  }
+  ASSERT_TRUE(PEMToDER(&data, &data_len, kRootCAPEM));
 
   std::unique_ptr<uint8_t[]> data_with_trailing_byte(new uint8_t[data_len + 1]);
   OPENSSL_memcpy(data_with_trailing_byte.get(), data.get(), data_len);
@@ -1069,22 +894,15 @@
 
   bssl::UniquePtr<CRYPTO_BUFFER> buf_with_trailing_byte(
       CRYPTO_BUFFER_new(data_with_trailing_byte.get(), data_len + 1, nullptr));
-  if (!buf_with_trailing_byte) {
-    return false;
-  }
+  ASSERT_TRUE(buf_with_trailing_byte);
 
   bssl::UniquePtr<X509> root(
       X509_parse_from_buffer(buf_with_trailing_byte.get()));
-  if (root) {
-    fprintf(stderr, "Parsed buffer with trailing byte.\n");
-    return false;
-  }
+  ASSERT_FALSE(root);
   ERR_clear_error();
-
-  return true;
 }
 
-static bool TestPrintUTCTIME() {
+TEST(X509Test, TestPrintUTCTIME) {
   static const struct {
     const char *val, *want;
   } asn1_utctime_tests[] = {
@@ -1116,6 +934,7 @@
   };
 
   for (auto t : asn1_utctime_tests) {
+    SCOPED_TRACE(t.val);
     bssl::UniquePtr<ASN1_UTCTIME> tm(ASN1_UTCTIME_new());
     bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
 
@@ -1123,53 +942,14 @@
     // type-confused and pass ASN1_GENERALIZEDTIME to ASN1_UTCTIME_print().
     // ASN1_UTCTIME_set_string() is stricter, and would reject the inputs in
     // question.
-    if (!ASN1_STRING_set(tm.get(), t.val, strlen(t.val))) {
-      fprintf(stderr, "ASN1_STRING_set\n");
-      return false;
-    }
+    ASSERT_TRUE(ASN1_STRING_set(tm.get(), t.val, strlen(t.val)));
     const int ok = ASN1_UTCTIME_print(bio.get(), tm.get());
 
     const uint8_t *contents;
     size_t len;
-    if (!BIO_mem_contents(bio.get(), &contents, &len)) {
-      fprintf(stderr, "BIO_mem_contents\n");
-      return false;
-    }
-
-    if (ok != (strcmp(t.want, "Bad time value") != 0)) {
-      fprintf(stderr, "ASN1_UTCTIME_print(%s): bad return value\n", t.val);
-      return false;
-    }
-    if (len != strlen(t.want) || memcmp(contents, t.want, len)) {
-      fprintf(stderr, "ASN1_UTCTIME_print(%s): got %.*s, want %s\n", t.val,
-              static_cast<int>(len),
-              reinterpret_cast<const char *>(contents), t.want);
-      return false;
-    }
+    ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len));
+    EXPECT_EQ(ok, (strcmp(t.want, "Bad time value") != 0) ? 1 : 0);
+    EXPECT_EQ(t.want,
+              std::string(reinterpret_cast<const char *>(contents), len));
   }
-
-  return true;
-}
-
-int main() {
-  CRYPTO_library_init();
-
-  if (!TestVerify() ||
-      !TestCRL() ||
-      !TestPSS() ||
-      !TestBadPSSParameters() ||
-      !TestEd25519() ||
-      !TestBadEd25519Parameters() ||
-      !TestSignCtx() ||
-      !TestFromBuffer() ||
-      !TestFromBufferTrailingData() ||
-      !TestFromBufferModified() ||
-      !TestFromBufferReused() ||
-      !TestFailedParseFromBuffer() ||
-      !TestPrintUTCTIME()) {
-    return 1;
-  }
-
-  printf("PASS\n");
-  return 0;
 }
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index 27b58f4..2413a1c 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -146,12 +146,6 @@
     return ok;
 }
 
-#if 0
-static int x509_subject_cmp(X509 **a, X509 **b)
-{
-    return X509_subject_name_cmp(*a, *b);
-}
-#endif
 /* Return 1 is a certificate is self signed */
 static int cert_self_signed(X509 *x)
 {
@@ -2101,7 +2095,7 @@
 
 int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
                                     CRYPTO_EX_unused * unused,
-                                    CRYPTO_EX_dup *dup_func,
+                                    CRYPTO_EX_dup *dup_unused,
                                     CRYPTO_EX_free *free_func)
 {
     /*
@@ -2110,7 +2104,7 @@
      */
     int index;
     if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
-                                 dup_func, free_func)) {
+                                 free_func)) {
         return -1;
     }
     return index;
diff --git a/src/crypto/x509/x509type.c b/src/crypto/x509/x509type.c
deleted file mode 100644
index d4f5a4d..0000000
--- a/src/crypto/x509/x509type.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.] */
-
-#include <openssl/evp.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
-
-int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
-{
-    EVP_PKEY *pk;
-    int ret = 0, i;
-
-    if (x == NULL)
-        return (0);
-
-    if (pkey == NULL)
-        pk = X509_get_pubkey(x);
-    else
-        pk = pkey;
-
-    if (pk == NULL)
-        return (0);
-
-    switch (pk->type) {
-    case EVP_PKEY_RSA:
-        ret = EVP_PK_RSA | EVP_PKT_SIGN;
-/*              if (!sign only extension) */
-        ret |= EVP_PKT_ENC;
-        break;
-    case EVP_PKEY_DSA:
-        ret = EVP_PK_DSA | EVP_PKT_SIGN;
-        break;
-    case EVP_PKEY_EC:
-        ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
-        break;
-    case EVP_PKEY_DH:
-        ret = EVP_PK_DH | EVP_PKT_EXCH;
-        break;
-    case NID_id_GostR3410_94:
-    case NID_id_GostR3410_2001:
-        ret = EVP_PKT_EXCH | EVP_PKT_SIGN;
-        break;
-    default:
-        break;
-    }
-
-    i = OBJ_obj2nid(x->sig_alg->algorithm);
-    if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
-
-        switch (i) {
-        case NID_rsaEncryption:
-        case NID_rsa:
-            ret |= EVP_PKS_RSA;
-            break;
-        case NID_dsa:
-        case NID_dsa_2:
-            ret |= EVP_PKS_DSA;
-            break;
-        case NID_X9_62_id_ecPublicKey:
-            ret |= EVP_PKS_EC;
-            break;
-        default:
-            break;
-        }
-    }
-
-    if (EVP_PKEY_size(pk) <= 1024 / 8) /* /8 because it's 1024 bits we look
-                                        * for, not bytes */
-        ret |= EVP_PKT_EXP;
-    if (pkey == NULL)
-        EVP_PKEY_free(pk);
-    return (ret);
-}
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index 4abdc91..e6eeb95 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -71,7 +71,7 @@
 
 
 typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
-DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
 
 /*
  * Maximum length of X509_NAME: much larger than anything we should
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index 15118d2..9edfa00 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -188,11 +188,11 @@
 }
 
 int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused,
-                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+                          CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func)
 {
     int index;
     if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
-                                 dup_func, free_func)) {
+                                 free_func)) {
         return -1;
     }
     return index;
diff --git a/src/crypto/x509/x_x509a.c b/src/crypto/x509/x_x509a.c
index a63ee42..dccc46a 100644
--- a/src/crypto/x509/x_x509a.c
+++ b/src/crypto/x509/x_x509a.c
@@ -196,10 +196,3 @@
         x->aux->reject = NULL;
     }
 }
-
-ASN1_SEQUENCE(X509_CERT_PAIR) = {
-        ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
-        ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
-} ASN1_SEQUENCE_END(X509_CERT_PAIR)
-
-IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)