Hi! attached are manual pages for SSL_CTX_set_verify() and friends including the *_set_verify_depth() functions as of the discussion about the exact functionality. I have also added some more information to SSL_CTX_load_verify_locations() as the result of a discussion on openssl-users, where expired certificates came into the way of more actual ones. Best regards, Lutz -- Lutz Jaenicke [EMAIL PROTECTED] BTU Cottbus http://www.aet.TU-Cottbus.DE/personen/jaenicke/ Lehrstuhl Allgemeine Elektrotechnik Tel. +49 355 69-4129 Universitaetsplatz 3-4, D-03044 Cottbus Fax. +49 355 69-4153
diff -r -u --new-file openssl-SNAP-20001011-vanilla/doc/ssl/SSL_CTX_get_verify_mode.pod openssl-SNAP-20001011/doc/ssl/SSL_CTX_get_verify_mode.pod --- openssl-SNAP-20001011-vanilla/doc/ssl/SSL_CTX_get_verify_mode.pod Thu Jan 1 01:00:00 1970 +++ openssl-SNAP-20001011/doc/ssl/SSL_CTX_get_verify_mode.pod Thu Oct 12 11:28:43 +2000 @@ -0,0 +1,50 @@ +=pod + +=head1 NAME + +SSL_CTX_get_verify_mode, SSL_get_verify_mode, SSL_CTX_get_verify_depth, +SSL_get_verify_depth, SSL_get_verify_callback, SSL_CTX_get_verify_callback - get +currently set verification parameters + +=head1 SYNOPSIS + + #include <openssl/ssl.h> + + int SSL_CTX_get_verify_mode(SSL_CTX *ctx); + int SSL_get_verify_mode(SSL *ssl); + int SSL_CTX_get_verify_depth(SSL_CTX *ctx); + int SSL_get_verify_depth(SSL *ssl); + int (*SSL_CTX_get_verify_callback(SSL_CTX *ctx))(int, X509_STORE_CTX *); + int (*SSL_get_verify_callback(SSL *ssl))(int, X509_STORE_CTX *); + +=head1 DESCRIPTION + +SSL_CTX_get_verify_mode() returns the verification mode currently set in +B<ctx>. + +SSL_get_verify_mode() returns the verification mode currently set in +B<ssl>. + +SSL_CTX_get_verify_depth() returns the verification depth limit currently set +in B<ctx>. If no limit has been explicitly set, -1 is returned and the +default value will be used. + +SSL_get_verify_depth() returns the verification depth limit currently set +in B<ssl>. If no limit has been explicitly set, -1 is returned and the +default value will be used. + +SSL_CTX_get_verify_callback() returns a function pointer to the verification +callback currently set in B<ctx>. If no callback was explicitly set, the +NULL pointer is returned and the default callback will be used. + +SSL_get_verify_callback() returns a function pointer to the verification +callback currently set in B<ssl>. If no callback was explicitly set, the +NULL pointer is returned and the default callback will be used. + +=head1 RETURN VALUES + +See DESCRIPTION + +=head1 SEE ALSO + +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)> + +=cut diff -r -u --new-file openssl-SNAP-20001011-vanilla/doc/ssl/SSL_CTX_load_verify_locations.pod openssl-SNAP-20001011/doc/ssl/SSL_CTX_load_verify_locations.pod --- openssl-SNAP-20001011-vanilla/doc/ssl/SSL_CTX_load_verify_locations.pod Tue Oct 10 12:01:06 2000 +++ openssl-SNAP-20001011/doc/ssl/SSL_CTX_load_verify_locations.pod Thu Oct 12 +11:11:27 2000 @@ -40,6 +40,10 @@ If B<CApath> is not NULL, it points to a directory containing CA certificates in PEM format. The files each contain one CA certificate. The files are looked up by the CA subject name hash value, which must hence be available. +If more than one CA certificate with the same name hash value exist, the +extension must be different (e.g. 9d66eef0.0, 9d66eef0.1 etc). The search +is performed in the ordering of the extension number, regardless of other +properties of the certificates. Use the B<c_rehash> utility to create the necessary links. The certificates in B<CAfile> are only looked up when required, e.g. when @@ -48,6 +52,24 @@ On a server, the certificates in B<CApath> are not listed as available CA certificates to a client during a TLS/SSL handshake. + +When looking up CA certificates, the OpenSSL library will first search the +certificates in B<CAfile>, then those in B<CApath>. Certificate matching +is done based on the subject name, the key identifier (if present), and the +serial number as taken from the certificate to be verified. If these data +do not match, the next certificate will be tried. If a first certificate +matching the parameters is found, the verification process will be performed; +no other certificates for the same parameters will be searched in case of +failure. + +=head1 WARNINGS + +If several CA certificates matching the name, key identifier, and serial +number condition are available, only the first one will be examined. This +may lead to unexpected results if the same CA certificate is available +with different expiration dates. If a "certificate expired" verification +error occurs, no other certificate will be searched. Make sure to not +have expired certificates mixed with valid ones. =head1 EXAMPLES diff -r -u --new-file openssl-SNAP-20001011-vanilla/doc/ssl/SSL_CTX_set_verify.pod openssl-SNAP-20001011/doc/ssl/SSL_CTX_set_verify.pod --- openssl-SNAP-20001011-vanilla/doc/ssl/SSL_CTX_set_verify.pod Thu Jan 1 01:00:00 1970 +++ openssl-SNAP-20001011/doc/ssl/SSL_CTX_set_verify.pod Thu Oct 12 11:27:18 +2000 @@ -0,0 +1,251 @@ +=pod + +=head1 NAME + +SSL_CTX_set_verify, SSL_set_verify, SSL_CTX_set_verify_depth, SSL_set_verify_depth - +set peer certificate verification parameters + +=head1 SYNOPSIS + + #include <openssl/ssl.h> + + void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*verify_callback)(int, X509_STORE_CTX *)); + void SSL_set_verify(SSL *s, int mode, + int (*verify_callback)(int, X509_STORE_CTX *)); + void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth); + void SSL_set_verify_depth(SSL *s, int depth); + + int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); + +=head1 DESCRIPTION + +SSL_CTX_set_verify() sets the verification flags for B<ctx> to be B<mode> and +specifies the B<verify_callback> function to be used. If no callback function +shall be specified, the NULL pointer can be used for B<verify_callback>. + +SSL_set_verify() sets the verification flags for B<ssl> to be B<mode> and +specifies the B<verify_callback> function to be used. If no callback function +shall be specified, the NULL pointer can be used for B<verify_callback>. In +this case last B<verify_callback> set specifically for this B<ssl> remains. If +no special B<callback> was set before, the default callback for the underlying +B<ctx> is used, that was valid at the the time B<ssl> was created with +L<SSL_new(3)|SSL_new(3)>. + +SSL_CTX_set_verify_depth() sets the maximum B<depth> for the certificate chain +verification that shall be allowed for B<ctx>. (See the BUGS section.) + +SSL_set_verify_depth() sets the maximum B<depth> for the certificate chain +verification that shall be allowed for B<ssl>. (See the BUGS section.) + +=head1 NOTES + +The verification of certificates can be controlled by a set of logically +or'ed B<mode> flags: + +=over 4 + +=item SSL_VERIFY_NONE + +B<Server mode:> the server will not send a client certificate request to the +client, so the client will not send a certificate. + +B<Client mode:> if not using an anonymous cipher (by default disabled), the +server will send a certificate which will be checked. The result of the +certificate verification process can be checked after the TLS/SSL handshake +using the L<SSL_get_verify_result(3)|SSL_get_verify_result(3)> function. +The handshake will be continued regardless of the verification result. + +=item SSL_VERIFY_PEER + +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 +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 +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. + +=item SSL_VERIFY_FAIL_IF_NO_PEER_CERT + +B<Server mode:> if the client did not return a certificate, the TLS/SSL +handshake is immediately terminated with a "handshake failure" alert. +This flag must be used together with SSL_VERIFY_PEER. + +B<Client mode:> ignored + +=item SSL_VERIFY_CLIENT_ONCE + +B<Server mode:> only request a client certificate on the initial TLS/SSL +handshake. Do not ask for a client certificate again in case of a +renegotiation. This flag must be used together with SSL_VERIFY_PEER. + +B<Client mode:> ignored + +=back + +Exactly one of the B<mode> flags SSL_VERIFY_NONE and SSL_VERIFY_PEER must be +set at any time. + +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 +above the limit are ignored. Error messages are generated as if these +certificates would not be present, most likely a +X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY will be issued. +The depth count is "level 0:peer certificate", "level 1: CA certificate", +"level 2: higher level CA certificate", and so on. Setting the maximum +depth to 2 allows the levels 0, 1, and 2. The default depth limit is 9, +allowing for the peer certificate and additional 9 CA certificates. + +The B<verify_callback> function is used to control the behaviour when the +SSL_VERIFY_PEER flag is set. It must be supplied by the application and +receives two arguments: B<preverify_ok> indicates, whether the verification of +the certificate in question was passed (preverify_ok=1) or not +(preverify_ok=0). B<x509_ctx> is a pointer to the complete context used +for the certificate chain verification. + +The certificate chain is checked starting with the deepest nesting level +(the root CA certificate) and worked upward to the peer's certificate. +At each level signatures and issuer attributes are checked. Whenever +a verification error is found, the error number is stored in B<x509_ctx> +and B<verify_callback> is called with B<preverify_ok>=0. By applying +X509_CTX_store_* functions B<verify_callback> can locate the certificate +in question and perform additional steps (see EXAMPLES). If no error is +found for a certificate, B<verify_callback> is called with B<preverify_ok>=1 +before advancing to the next level. + +The return value of B<verify_callback> controls the strategy of the further +verification process. If B<verify_callback> returns 0, the verification +process is immediately stopped with "verification failed" state. If +SSL_VERIFY_PEER is set, a verification failure alert is sent to the peer and +the TLS/SSL handshake is terminated. If B<verify_callback> returns 1, +the verification process is continued. If B<verify_callback> always returns +1, the TLS/SSL handshake will never be terminated because of this application +experiencing a verification failure. The calling process can however +retrieve the error code of the last verification error using +L<SSL_get_verify_result(3)|SSL_get_verify_result(3)> or by maintaining its +own error storage managed by B<verify_callback>. + +If no B<verify_callback> is specified, the default callback will be used. +Its return value is identical to B<preverify_ok>, so that any verification +failure will lead to a termination of the TLS/SSL handshake with an +alert message, if SSL_VERIFY_PEER is set. + +=head1 BUGS + +In client mode, it is not checked whether the SSL_VERIFY_PEER flag +is set, but whether SSL_VERIFY_NONE is not set. This can lead to +unexpected behaviour, if the SSL_VERIFY_PEER and SSL_VERIFY_NONE are not +used as required (exactly one must be set at any time). + +The certificate verification depth set with SSL[_CTX]_verify_depth() +stops the verification at a certain depth. The error message produced +will be that of an incomplete certificate chain and not +X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected. + +=head1 RETURN VALUES + +The SSL*_set_verify*() functions do not provide diagnostic information. + +=head1 EXAMPLES + +The following code sequence realizes an example B<verify_callback> function +that will always continue the TLS/SSL handshake regardless of verification +failure, if wished. The callback realizes a verification depth limit with +more informational output. + +All verification errors are printed, informations about the certificate chain +are printed on request. +The example is realized for a server that does allow but not require client +certificates. + + ... + int verbose_mode; + int verify_depth; + int always_continue; + ... + static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) + { + char buf[256]; + 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); + + X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); + + /* + * Catch a too long certificate chain. The depth limit set using + * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so + * that whenever the "depth>verify_depth" condition is met, we + * have violated the limit and want to log this error condition. + * We must do it here, because the CHAIN_TO_LONG error would not + * be found explicitly; only errors introduced by cutting off the + * additional certificates would be logged. + */ + if (depth > verify_depth) { + preverify_ok = 0; + err = X509_V_ERR_CERT_CHAIN_TOO_LONG; + X509_STORE_CTX_set_error(ctx, err); + } + if (!preverify_ok) { + printf("verify error:num=%d:%s:depth=%d:%s\n", err, + X509_verify_cert_error_string(err), depth, buf); + } + else if (verbose_mode) + { + printf("depth=%d:%s\n", depth, buf); + } + + /* + * At this point, err contains the last verification error. We can use + * it for something special + */ + if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) + { + X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); + printf("issuer= %s\n", buf); + } + + if (always_continue) + return 1; + else + return preverify_ok; + } + ... + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, + verify_callback); + + /* + * Let the verify_callback catch the verify_depth error so that we get + * an appropriate error in the logfile. + */ + SSL_CTX_set_verify_depth(verify_depth + 1); + + ... + SSL_accept(ssl); /* check of success left out for clarity */ + if (peer = SSL_get_peer_certificate(ssl)) + { + if (SSL_get_verify_result(ssl) == X509_V_OK) + { + /* The client sent a certificate which verified OK */ + } + } + +=head1 SEE ALSO + +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)> + +=cut diff -r -u --new-file openssl-SNAP-20001011-vanilla/doc/ssl/ssl.pod openssl-SNAP-20001011/doc/ssl/ssl.pod --- openssl-SNAP-20001011-vanilla/doc/ssl/ssl.pod Wed Oct 4 01:00:55 2000 +++ openssl-SNAP-20001011/doc/ssl/ssl.pod Thu Oct 12 11:26:44 2000 @@ -626,10 +626,13 @@ L<openssl(1)|openssl(1)>, L<crypto(3)|crypto(3)>, L<SSL_accept(3)|SSL_accept(3)>, L<SSL_clear(3)|SSL_clear(3)>, L<SSL_connect(3)|SSL_connect(3)>, +L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>, +L<SSL_CTX_get_verify_mode(3)|SSL_CTX_get_verify_mode(3)>, L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)> L<SSL_CTX_new(3)|SSL_CTX_new(3)>, L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)> L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)>, +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>, L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>, L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>, L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_get_fd(3)|SSL_get_fd(3)>,