[openssl] master update

dev at ddvo.net dev at ddvo.net
Sat Feb 6 17:54:19 UTC 2021


The branch master has been updated
       via  11ddbf84597d26c937ecb8f266424dea7f72cbdf (commit)
      from  2bb05a9668323ac2719f84cf8e9ccffc2bc99916 (commit)


- Log -----------------------------------------------------------------
commit 11ddbf84597d26c937ecb8f266424dea7f72cbdf
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu Jan 28 00:28:25 2021 +0100

    Add X509_STORE_CTX_verify(), which takes the first untrusted cert as default target
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14021)

-----------------------------------------------------------------------

Summary of changes:
 crypto/x509/x509_vfy.c                | 18 ++++++++++++--
 doc/man3/X509_STORE_CTX_get_error.pod | 12 +++++-----
 doc/man3/X509_STORE_CTX_new.pod       | 44 ++++++++++++++++++++++-------------
 doc/man3/X509_verify_cert.pod         | 41 ++++++++++++++++++--------------
 include/openssl/x509.h.in             |  2 --
 include/openssl/x509_vfy.h.in         |  3 +++
 test/danetest.c                       |  6 ++---
 util/libcrypto.num                    |  1 +
 8 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index ec7df5caa6..d55808e524 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -237,11 +237,25 @@ static int verify_chain(X509_STORE_CTX *ctx)
     return ok;
 }
 
+int X509_STORE_CTX_verify(X509_STORE_CTX *ctx)
+{
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+    }
+    if (ctx->cert == NULL && sk_X509_num(ctx->untrusted) >= 1)
+        ctx->cert = sk_X509_value(ctx->untrusted, 0);
+    return X509_verify_cert(ctx);
+}
+
 int X509_verify_cert(X509_STORE_CTX *ctx)
 {
-    SSL_DANE *dane = ctx->dane;
     int ret;
 
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+    }
     if (ctx->cert == NULL) {
         ERR_raise(ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
         ctx->error = X509_V_ERR_INVALID_CALL;
@@ -268,7 +282,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
     CB_FAIL_IF(!check_key_level(ctx, ctx->cert),
                ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL);
 
-    ret = DANETLS_ENABLED(dane) ? dane_verify(ctx) : verify_chain(ctx);
+    ret = DANETLS_ENABLED(ctx->dane) ? dane_verify(ctx) : verify_chain(ctx);
 
     /*
      * Safety-net.  If we are returning an error, we must also set ctx->error,
diff --git a/doc/man3/X509_STORE_CTX_get_error.pod b/doc/man3/X509_STORE_CTX_get_error.pod
index e6a6b6b0ca..8d0e2ad2dc 100644
--- a/doc/man3/X509_STORE_CTX_get_error.pod
+++ b/doc/man3/X509_STORE_CTX_get_error.pod
@@ -27,7 +27,8 @@ information
 
 =head1 DESCRIPTION
 
-These functions are typically called after X509_verify_cert() has indicated
+These functions are typically called after certificate or chain verification
+using L<X509_verify_cert(3)> or L<X509_STORE_CTX_verify(3)> has indicated
 an error or in a verification callback to determine the nature of an error.
 
 X509_STORE_CTX_get_error() returns the error code of B<ctx>, see
@@ -65,10 +66,9 @@ X509_STORE_CTX_get0_cert() retrieves an internal pointer to the
 certificate being verified by the B<ctx>.
 
 X509_STORE_CTX_get1_chain() returns a complete validate chain if a previous
-call to X509_verify_cert() is successful. If the call to X509_verify_cert()
-is B<not> successful the returned chain may be incomplete or invalid. The
-returned chain persists after the B<ctx> structure is freed, when it is
-no longer needed it should be free up using:
+verification is successful. Otherwise the returned chain may be incomplete or
+invalid. The returned chain persists after the B<ctx> structure is freed,
+when it is no longer needed it should be free up using:
 
  sk_X509_pop_free(chain, X509_free);
 
@@ -459,7 +459,7 @@ thread safe but will never happen unless an invalid code is passed.
 
 =head1 SEE ALSO
 
-L<X509_verify_cert(3)>,
+L<X509_verify_cert(3)>, L<X509_STORE_CTX_verify(3)>,
 L<X509_up_ref(3)>,
 L<X509_free(3)>.
 
diff --git a/doc/man3/X509_STORE_CTX_new.pod b/doc/man3/X509_STORE_CTX_new.pod
index b5ef577310..e98dcc7cfa 100644
--- a/doc/man3/X509_STORE_CTX_new.pod
+++ b/doc/man3/X509_STORE_CTX_new.pod
@@ -23,8 +23,8 @@ X509_STORE_CTX_verify_fn
  void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
  void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
 
- int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
-                         X509 *x509, STACK_OF(X509) *chain);
+ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *trust_store,
+                         X509 *target, STACK_OF(X509) *untrusted);
 
  void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
 
@@ -48,7 +48,7 @@ X509_STORE_CTX_verify_fn
 =head1 DESCRIPTION
 
 These functions initialise an B<X509_STORE_CTX> structure for subsequent use
-by X509_verify_cert().
+by L<X509_verify_cert(3)> or L<X509_STORE_CTX_verify(3)>.
 
 X509_STORE_CTX_new_ex() returns a newly initialised B<X509_STORE_CTX>
 structure associated with the specified library context I<libctx> and property
@@ -67,22 +67,31 @@ is no longer valid.
 If I<ctx> is NULL nothing is done.
 
 X509_STORE_CTX_init() sets up I<ctx> for a subsequent verification operation.
-It must be called before each call to X509_verify_cert(), i.e. a I<ctx> is only
-good for one call to X509_verify_cert(); if you want to verify a second
-certificate with the same I<ctx> then you must call X509_STORE_CTX_cleanup()
+It must be called before each call to L<X509_verify_cert(3)>, i.e., a I<ctx> is
+only good for one verification; if you want to verify a second certificate
+or chain with the same I<ctx> then you must call X509_STORE_CTX_cleanup()
 and then X509_STORE_CTX_init() again before the second call to
-X509_verify_cert(). The trusted certificate store is set to I<store>, the end
-entity certificate to be verified is set to I<x509> and a set of additional
-certificates (which will be untrusted but may be used to build the chain) in
-I<chain>. Any or all of the I<store>, I<x509> and I<chain> parameters can be
-B<NULL>.
+L<X509_verify_cert(3)> or L<X509_STORE_CTX_verify(3)>.
+The trusted certificate store is set to I<trust_store> of type B<X509_STORE>.
+This may be NULL because there are no trusted certificates or because
+they are provided simply as a list using X509_STORE_CTX_set0_trusted_stack().
+The end entity certificate to be verified is set to I<target>,
+and a list of additional certificates may be provided in I<untrusted>,
+which will not be trusted but may be used to build the chain.
+Each of the I<trust_store>, I<target> and I<untrusted> parameters can be
+B<NULL>. Yet note that L<X509_verify_cert(3)> and L<X509_STORE_CTX_verify(3)>
+will need a verification target.
+This can also be set using X509_STORE_CTX_set_cert().
+For L<X509_STORE_CTX_verify(3)>, which takes by default the first element of the
+list of untrusted certificates as its verification target,
+this can be also set indirectly using X509_STORE_CTX_set0_untrusted().
 
 X509_STORE_CTX_set0_trusted_stack() sets the set of trusted certificates of
 I<ctx> to I<sk>. This is an alternative way of specifying trusted certificates
 instead of using an B<X509_STORE>.
 
-X509_STORE_CTX_set_cert() sets the certificate to be verified in I<ctx> to
-I<x>.
+X509_STORE_CTX_set_cert() sets the target certificate to be verified in I<ctx>
+to I<x>.
 
 X509_STORE_CTX_set0_verified_chain() sets the validated chain used
 by I<ctx> to be I<chain>.
@@ -103,8 +112,10 @@ to the verification parameters associated with I<ctx>.
 X509_STORE_CTX_get0_untrusted() retrieves an internal pointer to the
 stack of untrusted certificates associated with I<ctx>.
 
-X509_STORE_CTX_set0_untrusted() sets the internal point to the stack
+X509_STORE_CTX_set0_untrusted() sets the internal pointer to the stack
 of untrusted certificates associated with I<ctx> to I<sk>.
+X509_STORE_CTX_verify() will take the first element, if any,
+as its default target if the target certificate is not set explicitly.
 
 X509_STORE_CTX_set0_param() sets the internal verification parameter pointer
 to I<param>. After this call B<param> should not be used.
@@ -114,7 +125,8 @@ method to I<name>. This uses the function X509_VERIFY_PARAM_lookup() to
 find an appropriate set of parameters from I<name>.
 
 X509_STORE_CTX_get_num_untrusted() returns the number of untrusted certificates
-that were used in building the chain following a call to X509_verify_cert().
+that were used in building the chain following a call to L<X509_verify_cert(3)>.
+With L<X509_STORE_CTX_verify(3)>, this does not count the first chain element.
 
 X509_STORE_CTX_set_verify() provides the capability for overriding the default
 verify function. This function is responsible for verifying chain signatures and
@@ -162,7 +174,7 @@ used.
 
 =head1 SEE ALSO
 
-L<X509_verify_cert(3)>
+L<X509_verify_cert(3)>, L<X509_STORE_CTX_verify(3)>,
 L<X509_VERIFY_PARAM_set_flags(3)>
 
 =head1 HISTORY
diff --git a/doc/man3/X509_verify_cert.pod b/doc/man3/X509_verify_cert.pod
index c60d27ac12..13854f5ed6 100644
--- a/doc/man3/X509_verify_cert.pod
+++ b/doc/man3/X509_verify_cert.pod
@@ -2,22 +2,25 @@
 
 =head1 NAME
 
-X509_verify_cert - discover and verify X509 certificate chain
+X509_verify_cert,
+X509_STORE_CTX_verify - discover and verify X509 certificate chain
 
 =head1 SYNOPSIS
 
- #include <openssl/x509.h>
+ #include <openssl/x509_vfy.h>
 
  int X509_verify_cert(X509_STORE_CTX *ctx);
+ int X509_STORE_CTX_verify(X509_STORE_CTX *ctx);
 
 =head1 DESCRIPTION
 
 The X509_verify_cert() function attempts to discover and validate a
-certificate chain based on parameters in B<ctx>.
+certificate chain based on parameters in I<ctx>.
 The verification context, of type B<X509_STORE_CTX>, can be constructed
 using L<X509_STORE_CTX_new(3)> and L<X509_STORE_CTX_init(3)>.
-It usually includes a set of certificates serving as trust anchors,
-a set of non-trusted certificates that may be needed for chain construction,
+It usually includes a target certificate to be verified,
+a set of certificates serving as trust anchors,
+a list of non-trusted certificates that may be helpful for chain construction,
 flags such as X509_V_FLAG_X509_STRICT, and various other optional components
 such as a callback function that allows customizing the verification outcome.
 A complete description of the certificate verification process is contained in
@@ -28,33 +31,35 @@ OpenSSL internally for certificate validation, in both the S/MIME and
 SSL/TLS code.
 
 A negative return value from X509_verify_cert() can occur if it is invoked
-incorrectly, such as with no certificate set in B<ctx>, or when it is called
-twice in succession without reinitialising B<ctx> for the second call.
+incorrectly, such as with no certificate set in I<ctx>, or when it is called
+twice in succession without reinitialising I<ctx> for the second call.
 A negative return value can also happen due to internal resource problems or if
 a retry operation is requested during internal lookups (which never happens
 with standard lookup methods).
 Applications must check for <= 0 return value on error.
 
-=head1 RETURN VALUES
-
-If a complete chain can be built and validated this function returns 1,
-otherwise it return zero, in exceptional circumstances it can also
-return a negative code.
+The X509_STORE_CTX_verify() behaves like X509_verify_cert() except that its
+target certificate is the first element of the list of untrusted certificates
+in I<ctx> unless a target certificate is set explicitly.
 
-If the function fails additional error information can be obtained by
-examining B<ctx> using, for example L<X509_STORE_CTX_get_error(3)>.
+=head1 RETURN VALUES
 
-=head1 BUGS
+Both functions return 1 if a complete chain can be built and validated,
+otherwise they return 0, and in exceptional circumstances (such as malloc
+failure and internal errors) they can also return a negative code.
 
-This function uses the header F<< <openssl/x509.h> >>
-as opposed to most chain verification
-functions which use F<< <openssl/x509_vfy.h> >>.
+On error or failure additional error information can be obtained by
+examining I<ctx> using, for example, L<X509_STORE_CTX_get_error(3)>.
 
 =head1 SEE ALSO
 
 L<X509_STORE_CTX_new(3)>, L<X509_STORE_CTX_init(3)>,
 L<X509_STORE_CTX_get_error(3)>
 
+=head1 HISTORY
+
+X509_STORE_CTX_verify() was added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in
index 7aef798e5b..7fc1558b18 100644
--- a/include/openssl/x509.h.in
+++ b/include/openssl/x509.h.in
@@ -1042,8 +1042,6 @@ int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
                               const char *attrname, int type,
                               const unsigned char *bytes, int len);
 
-int X509_verify_cert(X509_STORE_CTX *ctx);
-
 /* lookup a cert from a X509 STACK */
 X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, const X509_NAME *name,
                                      const ASN1_INTEGER *serial);
diff --git a/include/openssl/x509_vfy.h.in b/include/openssl/x509_vfy.h.in
index f4ab746f75..b72513272f 100644
--- a/include/openssl/x509_vfy.h.in
+++ b/include/openssl/x509_vfy.h.in
@@ -72,6 +72,9 @@ typedef enum {
     .generate_stack_macros("X509_VERIFY_PARAM");
 -}
 
+int X509_verify_cert(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_verify(X509_STORE_CTX *ctx);
+
 int X509_STORE_set_depth(X509_STORE *store, int depth);
 
 typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *);
diff --git a/test/danetest.c b/test/danetest.c
index b0d6ffe563..25fd16a411 100644
--- a/test/danetest.c
+++ b/test/danetest.c
@@ -57,15 +57,13 @@ static int verify_chain(SSL *ssl, STACK_OF(X509) *chain)
     X509_STORE_CTX *store_ctx = NULL;
     SSL_CTX *ssl_ctx = NULL;
     X509_STORE *store = NULL;
-    X509 *cert = NULL;
     int ret = 0;
     int store_ctx_idx = SSL_get_ex_data_X509_STORE_CTX_idx();
 
     if (!TEST_ptr(store_ctx = X509_STORE_CTX_new())
             || !TEST_ptr(ssl_ctx = SSL_get_SSL_CTX(ssl))
             || !TEST_ptr(store = SSL_CTX_get_cert_store(ssl_ctx))
-            || !TEST_ptr(cert = sk_X509_value(chain, 0))
-            || !TEST_true(X509_STORE_CTX_init(store_ctx, store, cert, chain))
+            || !TEST_true(X509_STORE_CTX_init(store_ctx, store, NULL, chain))
             || !TEST_true(X509_STORE_CTX_set_ex_data(store_ctx, store_ctx_idx,
                                                      ssl)))
         goto end;
@@ -80,7 +78,7 @@ static int verify_chain(SSL *ssl, STACK_OF(X509) *chain)
         X509_STORE_CTX_set_verify_cb(store_ctx, SSL_get_verify_callback(ssl));
 
     /* Mask "internal failures" (-1) from our return value. */
-    if (!TEST_int_ge(ret = X509_verify_cert(store_ctx), 0))
+    if (!TEST_int_ge(ret = X509_STORE_CTX_verify(store_ctx), 0))
         ret = 0;
 
     SSL_set_verify_result(ssl, X509_STORE_CTX_get_error(store_ctx));
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 32e7779bce..c591ab8ec5 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4996,6 +4996,7 @@ EVP_PKEY_get_octet_string_param         ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_is_a                           ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_can_sign                       ?	3_0_0	EXIST::FUNCTION:
 X509_STORE_CTX_new_ex                   ?	3_0_0	EXIST::FUNCTION:
+X509_STORE_CTX_verify                   ?	3_0_0	EXIST::FUNCTION:
 CT_POLICY_EVAL_CTX_new_ex               ?	3_0_0	EXIST::FUNCTION:CT
 CTLOG_new_ex                            ?	3_0_0	EXIST::FUNCTION:CT
 CTLOG_new_from_base64_ex                ?	3_0_0	EXIST::FUNCTION:CT


More information about the openssl-commits mailing list