As discussed recently on openssl-users.
[openssl.git] / doc / ssl / SSL_CTX_set_verify.pod
index 9d7b7a90701fb258da68db18a568d0e87c8467f9..5bb21ca5357012ff5a1d5760854b31aa102829c5 100644 (file)
@@ -59,14 +59,14 @@ The handshake will be continued regardless of the verification result.
 
 B<Server mode:> the server sends a client certificate request to the client.
 The certificate returned (if any) is checked. If the verification process
-fails as indicated by B<verify_callback>, the TLS/SSL handshake is
+fails, the TLS/SSL handshake is
 immediately terminated with an alert message containing the reason for
 the verification failure.
 The behaviour can be controlled by the additional
 SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
 
 B<Client mode:> the server certificate is verified. If the verification process
-fails as indicated by B<verify_callback>, the TLS/SSL handshake is
+fails, the TLS/SSL handshake is
 immediately terminated with an alert message containing the reason for
 the verification failure. If no server certificate is sent, because an
 anonymous cipher is used, SSL_VERIFY_PEER is ignored.
@@ -92,6 +92,15 @@ B<Client mode:> ignored
 Exactly one of the B<mode> flags SSL_VERIFY_NONE and SSL_VERIFY_PEER must be
 set at any time.
 
+The actual verification procedure is performed either using the built-in
+verification procedure or using another application provided verification
+function set with
+L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>.
+The following descriptions apply in the case of the built-in procedure. An
+application provided procedure also has access to the verify depth information
+and the verify_callback() function, but the way this information is used
+may be different.
+
 SSL_CTX_set_verify_depth() and SSL_set_verify_depth() set the limit up
 to which depth certificates in a chain are used during the verification
 procedure. If the certificate chain is longer than allowed, the certificates
@@ -165,21 +174,38 @@ are printed on request.
 The example is realized for a server that does allow but not require client
 certificates.
 
+The example makes use of the ex_data technique to store application data
+into/retrieve application data from the SSL structure
+(see L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>,
+L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>).
+
  ...
- int verbose_mode;
- int verify_depth;
- int always_continue;
+ typedef struct {
+   int verbose_mode;
+   int verify_depth;
+   int always_continue;
+ } mydata_t;
+ int mydata_index;
  ...
  static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
  {
     char    buf[256];
     X509   *err_cert;
     int     err, depth;
+    SSL    *ssl;
+    mydata_t *mydata;
 
     err_cert = X509_STORE_CTX_get_current_cert(ctx);
     err = X509_STORE_CTX_get_error(ctx);
     depth = X509_STORE_CTX_get_error_depth(ctx);
 
+    /*
+     * Retrieve the pointer to the SSL of the connection currently treated
+     * and the application specific data stored into the SSL object.
+     */
+    ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+    mydata = SSL_get_ex_data(ssl, mydata_index);
+
     X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
 
     /*
@@ -191,7 +217,7 @@ certificates.
      * be found explicitly; only errors introduced by cutting off the
      * additional certificates would be logged.
      */
-    if (depth > verify_depth) {
+    if (depth > mydata->verify_depth) {
         preverify_ok = 0;
         err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
         X509_STORE_CTX_set_error(ctx, err);
@@ -200,7 +226,7 @@ certificates.
         printf("verify error:num=%d:%s:depth=%d:%s\n", err,
                  X509_verify_cert_error_string(err), depth, buf);
     }
-    else if (verbose_mode)
+    else if (mydata->verbose_mode)
     {
         printf("depth=%d:%s\n", depth, buf);
     }
@@ -215,11 +241,18 @@ certificates.
       printf("issuer= %s\n", buf);
     }
 
-    if (always_continue)
+    if (mydata->always_continue)
       return 1;
     else
       return preverify_ok;
  }
+ ...
+
+ mydata_t mydata;
+
+ ...
+ mydata_index = SSL_get_ex_new_index(0, "mydata index", NULL, NULL, NULL);
+
  ...
  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
                     verify_callback);
@@ -229,6 +262,13 @@ certificates.
   * an appropriate error in the logfile.
   */
  SSL_CTX_set_verify_depth(verify_depth + 1);
+
+ /*
+  * Set up the SSL specific data into "mydata" and store it into th SSL
+  * structure.
+  */
+ mydata.verify_depth = verify_depth; ...
+ SSL_set_ex_data(ssl, mydata_index, &mydata);
                                             
  ...
  SSL_accept(ssl);      /* check of success left out for clarity */
@@ -246,6 +286,9 @@ L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>,
 L<SSL_CTX_get_verify_mode(3)|SSL_CTX_get_verify_mode(3)>,
 L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
 L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
-L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>
+L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
+L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>,
+L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>,
+L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>
 
 =cut