Commit b5a6f0a9 authored by Lutz Jänicke's avatar Lutz Jänicke
Browse files

Documentation about SSL_get_ex_data_X509_STORE_CTX_idx and

SSL_get_ex_new_index() functionality. Extended verify_callback()
example to show the usage.
parent ba8e2824
Loading
Loading
Loading
Loading
+40 −7
Original line number Diff line number Diff line
@@ -165,21 +165,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)>).

 ...
 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 +208,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 +217,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 +232,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);
@@ -230,6 +254,13 @@ certificates.
  */
 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 */
 if (peer = SSL_get_peer_certificate(ssl))
@@ -246,6 +277,8 @@ 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_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
+61 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

SSL_get_ex_data_X509_STORE_CTX_idx - get ex_data index to access SSL structure
from X509_STORE_CTX

=head1 SYNOPSIS

 #include <openssl/ssl.h>

 int SSL_get_ex_data_X509_STORE_CTX_idx(void);

=head1 DESCRIPTION

SSL_get_ex_data_X509_STORE_CTX_idx() returns the index number under which
the pointer to the SSL object is stored into the X509_STORE_CTX object.

=head1 NOTES

Whenever a X509_STORE_CTX object is created for the verification of the
peers certificate during a handshake, a pointer to the SSL object is
stored into the X509_STORE_CTX object to identify the connection affected.
To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can
be used with the correct index. This index is globally the same for all
X509_STORE_CTX objects and can be retrieved using
SSL_get_ex_data_X509_STORE_CTX_idx(). The index value is set when
SSL_get_ex_data_X509_STORE_CTX_idx() is first called either by the application
program directly or indirectly during other SSL setup functions or during
the handshake.

The value depends on other index values defined for X509_STORE_CTX objects
before the SSL index is created.

=head1 RETURN VALUES

=over 4

=item E<gt>=0

The index value to access the pointer.

=item E<lt>0

An error occurred, check the error stack for a detailed error message.

=back

=head1 EXAMPLES

The index returned from SSL_get_ex_data_X509_STORE_CTX_idx() allows to
access the SSL object for the connection to be accessed during the
verify_callback() when checking the peers certificate. Please check
the example in L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,

=head1 SEE ALSO

L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>

=cut
+59 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

SSL_get_ex_new_index, SSL_set_ex_data, SSL_get_ex_data - internal application specific data functions

=head1 SYNOPSIS

 #include <openssl/ssl.h>

 int SSL_get_ex_new_index(long argl, void *argp,
                CRYPTO_EX_new *new_func,
                CRYPTO_EX_dup *dup_func,
                CRYPTO_EX_free *free_func);

 int SSL_set_ex_data(SSL *ssl, int idx, void *arg);

 void *SSL_get_ex_data(SSL *ssl, int idx);

 typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                int idx, long argl, void *argp);
 typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                int idx, long argl, void *argp);
 typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
                int idx, long argl, void *argp);

=head1 DESCRIPTION

Several OpenSSL structures can have application specific data attached to them.
These functions are used internally by OpenSSL to manipulate application
specific data attached to a specific structure.

SSL_get_ex_new_index() is used to register a new index for application
specific data.

SSL_set_ex_data() is used to store application data at B<arg> for B<idx> into
the B<ssl> object.

SSL_get_ex_data() is used to retrieve the information for B<idx> from
B<ssl>.

A detailed description for the B<*_get_ex_new_index()> functionality
can be found in L<RSA_get_ex_new_index.pod(3)|RSA_get_ex_new_index.pod(3)>.
The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.

=head1 EXAMPLES

An example on how to use the functionality is included in the example
verify_callback() in L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>.

=head1 SEE ALSO

L<ssl(3)|ssl(3)>,
L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>,
L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>

=cut