OLD | NEW |
(Empty) | |
| 1 =pod |
| 2 |
| 3 =head1 NAME |
| 4 |
| 5 X509_STORE_CTX_set_verify_cb - set verification callback |
| 6 |
| 7 =head1 SYNOPSIS |
| 8 |
| 9 #include <openssl/x509_vfy.h> |
| 10 |
| 11 void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, |
| 12 int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); |
| 13 |
| 14 =head1 DESCRIPTION |
| 15 |
| 16 X509_STORE_CTX_set_verify_cb() sets the verification callback of B<ctx> to |
| 17 B<verify_cb> overwriting any existing callback. |
| 18 |
| 19 The verification callback can be used to customise the operation of certificate |
| 20 verification, either by overriding error conditions or logging errors for |
| 21 debugging purposes. |
| 22 |
| 23 However a verification callback is B<not> essential and the default operation |
| 24 is often sufficient. |
| 25 |
| 26 The B<ok> parameter to the callback indicates the value the callback should |
| 27 return to retain the default behaviour. If it is zero then and error condition |
| 28 is indicated. If it is 1 then no error occurred. If the flag |
| 29 B<X509_V_FLAG_NOTIFY_POLICY> is set then B<ok> is set to 2 to indicate the |
| 30 policy checking is complete. |
| 31 |
| 32 The B<ctx> parameter to the callback is the B<X509_STORE_CTX> structure that |
| 33 is performing the verification operation. A callback can examine this |
| 34 structure and receive additional information about the error, for example |
| 35 by calling X509_STORE_CTX_get_current_cert(). Additional application data can |
| 36 be passed to the callback via the B<ex_data> mechanism. |
| 37 |
| 38 =head1 WARNING |
| 39 |
| 40 In general a verification callback should B<NOT> unconditionally return 1 in |
| 41 all circumstances because this will allow verification to succeed no matter |
| 42 what the error. This effectively removes all security from the application |
| 43 because B<any> certificate (including untrusted generated ones) will be |
| 44 accepted. |
| 45 |
| 46 =head1 NOTES |
| 47 |
| 48 The verification callback can be set and inherited from the parent structure |
| 49 performing the operation. In some cases (such as S/MIME verification) the |
| 50 B<X509_STORE_CTX> structure is created and destroyed internally and the |
| 51 only way to set a custom verification callback is by inheriting it from the |
| 52 associated B<X509_STORE>. |
| 53 |
| 54 =head1 RETURN VALUES |
| 55 |
| 56 X509_STORE_CTX_set_verify_cb() does not return a value. |
| 57 |
| 58 =head1 EXAMPLES |
| 59 |
| 60 Default callback operation: |
| 61 |
| 62 int verify_callback(int ok, X509_STORE_CTX *ctx) |
| 63 { |
| 64 return ok; |
| 65 } |
| 66 |
| 67 Simple example, suppose a certificate in the chain is expired and we wish |
| 68 to continue after this error: |
| 69 |
| 70 int verify_callback(int ok, X509_STORE_CTX *ctx) |
| 71 { |
| 72 /* Tolerate certificate expiration */ |
| 73 if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED) |
| 74 return 1; |
| 75 /* Otherwise don't override */ |
| 76 return ok; |
| 77 } |
| 78 |
| 79 More complex example, we don't wish to continue after B<any> certificate has |
| 80 expired just one specific case: |
| 81 |
| 82 int verify_callback(int ok, X509_STORE_CTX *ctx) |
| 83 { |
| 84 int err = X509_STORE_CTX_get_error(ctx); |
| 85 X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx); |
| 86 if (err == X509_V_ERR_CERT_HAS_EXPIRED) |
| 87 { |
| 88 if (check_is_acceptable_expired_cert(err_cert) |
| 89 return 1; |
| 90 } |
| 91 return ok; |
| 92 } |
| 93 |
| 94 Full featured logging callback. In this case the B<bio_err> is assumed to be |
| 95 a global logging B<BIO>, an alternative would to store a BIO in B<ctx> using |
| 96 B<ex_data>. |
| 97 |
| 98 int verify_callback(int ok, X509_STORE_CTX *ctx) |
| 99 { |
| 100 X509 *err_cert; |
| 101 int err,depth; |
| 102 |
| 103 err_cert = X509_STORE_CTX_get_current_cert(ctx); |
| 104 err = X509_STORE_CTX_get_error(ctx); |
| 105 depth = X509_STORE_CTX_get_error_depth(ctx); |
| 106 |
| 107 BIO_printf(bio_err,"depth=%d ",depth); |
| 108 if (err_cert) |
| 109 { |
| 110 X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), |
| 111 0, XN_FLAG_ONELINE); |
| 112 BIO_puts(bio_err, "\n"); |
| 113 } |
| 114 else |
| 115 BIO_puts(bio_err, "<no cert>\n"); |
| 116 if (!ok) |
| 117 BIO_printf(bio_err,"verify error:num=%d:%s\n",err, |
| 118 X509_verify_cert_error_string(err)); |
| 119 switch (err) |
| 120 { |
| 121 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: |
| 122 BIO_puts(bio_err,"issuer= "); |
| 123 X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), |
| 124 0, XN_FLAG_ONELINE); |
| 125 BIO_puts(bio_err, "\n"); |
| 126 break; |
| 127 case X509_V_ERR_CERT_NOT_YET_VALID: |
| 128 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: |
| 129 BIO_printf(bio_err,"notBefore="); |
| 130 ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); |
| 131 BIO_printf(bio_err,"\n"); |
| 132 break; |
| 133 case X509_V_ERR_CERT_HAS_EXPIRED: |
| 134 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: |
| 135 BIO_printf(bio_err,"notAfter="); |
| 136 ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); |
| 137 BIO_printf(bio_err,"\n"); |
| 138 break; |
| 139 case X509_V_ERR_NO_EXPLICIT_POLICY: |
| 140 policies_print(bio_err, ctx); |
| 141 break; |
| 142 } |
| 143 if (err == X509_V_OK && ok == 2) |
| 144 /* print out policies */ |
| 145 |
| 146 BIO_printf(bio_err,"verify return:%d\n",ok); |
| 147 return(ok); |
| 148 } |
| 149 |
| 150 =head1 SEE ALSO |
| 151 |
| 152 L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)> |
| 153 L<X509_STORE_set_verify_cb_func(3)|X509_STORE_set_verify_cb_func(3)> |
| 154 L<X509_STORE_CTX_get_ex_new_index(3)|X509_STORE_CTX_get_ex_new_index(3)> |
| 155 |
| 156 =head1 HISTORY |
| 157 |
| 158 X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and |
| 159 OpenSSL. |
| 160 |
| 161 =cut |
OLD | NEW |