Verification callback functions.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 18 Oct 2009 13:26:08 +0000 (13:26 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 18 Oct 2009 13:26:08 +0000 (13:26 +0000)
doc/crypto/X509_STORE_CTX_set_verify_cb.pod [new file with mode: 0644]
doc/crypto/X509_STORE_set_verify_cb_func.pod [new file with mode: 0644]

diff --git a/doc/crypto/X509_STORE_CTX_set_verify_cb.pod b/doc/crypto/X509_STORE_CTX_set_verify_cb.pod
new file mode 100644 (file)
index 0000000..b9787a6
--- /dev/null
@@ -0,0 +1,161 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_CTX_set_verify_cb - set verification callback
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+                               int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
+
+=head1 DESCRIPTION
+
+X509_STORE_CTX_set_verify_cb() sets the verification callback of B<ctx> to
+B<verify_cb> overwriting any existing callback.
+
+The verification callback can be used to customise the operation of certificate
+verification, either by overriding error conditions or logging errors for
+debugging purposes.
+
+However a verification callback is B<not> essential and the default operation
+is often sufficient.
+
+The B<ok> parameter to the callback indicates the value the callback should
+return to retain the default behaviour. If it is zero then and error condition
+is indicated. If it is 1 then no error occurred. If the flag
+B<X509_V_FLAG_NOTIFY_POLICY> is set then B<ok> is set to 2 to indicate the
+policy checking is complete.
+
+The B<ctx> parameter to the callback is the B<X509_STORE_CTX> structure that
+is performing the verification operation. A callback can examine this
+structure and receive additional information about the error, for example
+by calling X509_STORE_CTX_get_current_cert(). Additional application data can
+be passed to the callback via the B<ex_data> mechanism.
+
+=head1 WARNING
+
+In general a verification callback should B<NOT> unconditionally return 1 in
+all circumstances because this will allow verification to succeed no matter
+what the error. This effectively removes all security from the application
+because B<any> certificate (including untrusted generated ones) will be
+accepted.
+
+=head1 NOTES
+
+The verification callback can be set and inherited from the parent structure
+performing the operation. In some cases (such as S/MIME verification) the
+B<X509_STORE_CTX> structure is created and destroyed internally and the
+only way to set a custom verification callback is by inheriting it from the
+associated B<X509_STORE>.
+
+=head1 RETURN VALUES
+
+X509_STORE_CTX_set_verify_cb() does not return a value.
+
+=head1 EXAMPLES
+
+Default callback operation:
+
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+       {
+       return ok;
+       }
+
+Simple example, suppose a certificate in the chain is expired and we wish
+to continue after this error:
+
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+       {
+       /* Tolerate certificate expiration */
+       if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
+                       return 1;
+       /* Otherwise don't override */
+       return ok;
+       }
+
+More complex example, we don't wish to continue after B<any> certificate has
+expired just one specific case:
+
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+       {
+       int err = X509_STORE_CTX_get_error(ctx);
+       X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx);
+       if (err == X509_V_ERR_CERT_HAS_EXPIRED)
+               {
+               if (check_is_acceptable_expired_cert(err_cert)
+                       return 1;
+               }
+       return ok;
+       }
+
+Full featured logging callback. In this case the B<bio_err> is assumed to be
+a global logging B<BIO>, an alternative would to store a BIO in B<ctx> using
+B<ex_data>.
+       
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+       {
+       X509 *err_cert;
+       int err,depth;
+
+       err_cert = X509_STORE_CTX_get_current_cert(ctx);
+       err =   X509_STORE_CTX_get_error(ctx);
+       depth = X509_STORE_CTX_get_error_depth(ctx);
+
+       BIO_printf(bio_err,"depth=%d ",depth);
+       if (err_cert)
+               {
+               X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
+                                       0, XN_FLAG_ONELINE);
+               BIO_puts(bio_err, "\n");
+               }
+       else
+               BIO_puts(bio_err, "<no cert>\n");
+       if (!ok)
+               BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+                       X509_verify_cert_error_string(err));
+       switch (err)
+               {
+       case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+               BIO_puts(bio_err,"issuer= ");
+               X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
+                                       0, XN_FLAG_ONELINE);
+               BIO_puts(bio_err, "\n");
+               break;
+       case X509_V_ERR_CERT_NOT_YET_VALID:
+       case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+               BIO_printf(bio_err,"notBefore=");
+               ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
+               BIO_printf(bio_err,"\n");
+               break;
+       case X509_V_ERR_CERT_HAS_EXPIRED:
+       case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+               BIO_printf(bio_err,"notAfter=");
+               ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
+               BIO_printf(bio_err,"\n");
+               break;
+       case X509_V_ERR_NO_EXPLICIT_POLICY:
+               policies_print(bio_err, ctx);
+               break;
+               }
+       if (err == X509_V_OK && ok == 2)
+               /* print out policies */
+
+       BIO_printf(bio_err,"verify return:%d\n",ok);
+       return(ok);
+       }
+
+=head1 SEE ALSO
+
+L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
+L<X509_STORE_set_verify_cb_func(3)|X509_STORE_set_verify_cb_func(3)>
+L<X509_STORE_CTX_get_ex_new_index(3)|X509_STORE_CTX_get_ex_new_index(3)>
+
+=head1 HISTORY
+
+X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and
+OpenSSL.
+
+=cut
diff --git a/doc/crypto/X509_STORE_set_verify_cb_func.pod b/doc/crypto/X509_STORE_set_verify_cb_func.pod
new file mode 100644 (file)
index 0000000..1b774fc
--- /dev/null
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_set_verify_cb_func, X509_STORE_set_verify_cb - set verification callback
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ void X509_STORE_set_verify_cb(X509_STORE *st,
+                               int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
+
+ void X509_STORE_set_verify_cb_func(X509_STORE *st,
+                               int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
+
+=head1 DESCRIPTION
+
+X509_STORE_set_verify_cb() sets the verification callback of B<ctx> to
+B<verify_cb> overwriting any existing callback.
+
+X509_STORE_set_verify_cb_func() also sets the verification callback but it
+is implemented as a macro.
+
+=head 1 NOTES
+
+The verification callback from an B<X509_STORE> is inherited by 
+the corresponding B<X509_STORE_CTX> structure when it is initialized. This can
+be used to set the verification callback when the B<X509_STORE_CTX> is 
+otherwise inaccessible (for example during S/MIME verification).
+
+=head1 BUGS
+
+The macro version of this function was the only one available before 
+OpenSSL 1.0.0.
+
+=head1 RETURN VALUES
+
+X509_STORE_set_verify_cb() and X509_STORE_set_verify_cb_func() do not return
+a value.
+
+=head1 SEE ALSO
+
+L<X509_STORE_CTX_set_verify_cb(3)|X509_STORE_CTX_set_verify_cb(3)>
+L<CMS_verify(3)|CMS_verify(3)>
+
+=head1 HISTORY
+
+X509_STORE_set_verify_cb_func() is available in all versions of SSLeay and
+OpenSSL.
+
+X509_STORE_set_verify_cb() was added to OpenSSL 1.0.0.
+
+=cut