Support verify_depth from the SSL API without need for user-defined
authorBodo Möller <bodo@openssl.org>
Sat, 1 May 1999 03:20:40 +0000 (03:20 +0000)
committerBodo Möller <bodo@openssl.org>
Sat, 1 May 1999 03:20:40 +0000 (03:20 +0000)
callbacks.

Submitted by:
Reviewed by:
PR:

CHANGES
crypto/x509/x509_lu.c
crypto/x509/x509_vfy.c
crypto/x509/x509_vfy.h
ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_lib.c

diff --git a/CHANGES b/CHANGES
index 89bdc84b5cf040b56c49ba04522d4d8bb7828251..34908a34873f6855ffc9464bbd5be47dcd5b7d4f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,13 @@
 
  Changes between 0.9.2b and 0.9.3
 
+  *) Support verify_depth from the SSL API.
+     x509_vfy.c had what can be considered an off-by-one-error:
+     Its depth (which was not part of the external interface)
+     was actually counting the number of certificates in a chain;
+     now it really counts the depth.
+     [Bodo Moeller]
+
   *) New function SSL_CTX_set_session_id_context that allows to set a default
      value (so that you don't need SSL_set_session_id_context for each
      connection using the SSL_CTX).
index 2bdf613d4f04459131d4bdf1c2b3fcaf2932f1c7..d86e43776f3dc15b93a781cf93b3973684cceaa0 100644 (file)
@@ -391,7 +391,7 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
        ctx->last_untrusted=0;
        ctx->valid=0;
        ctx->chain=NULL;
-       ctx->depth=10;
+       ctx->depth=9;
        ctx->error=0;
        ctx->current_cert=NULL;
        memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA));
index 282d9f3dda7d9e34c10c4f1e4266b449eee6abfe..16fef853dd8cfe44b29501199065870a714833a2 100644 (file)
@@ -143,7 +143,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
        for (;;)
                {
                /* If we have enough, we break */
-               if (depth <= num) break;
+               if (depth < num) break;
 
                /* If we are self signed, we break */
                xn=X509_get_issuer_name(x);
@@ -206,7 +206,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
        for (;;)
                {
                /* If we have enough, we break */
-               if (depth <= num) break;
+               if (depth < num) break;
 
                /* If we are self signed, we break */
                xn=X509_get_issuer_name(x);
index e78f5abb565be1e1b515f18021844f5f53993585..1f89bf02255092b1dab1295577ef260bbbb34537 100644 (file)
@@ -169,7 +169,7 @@ typedef struct x509_store_st
 
        CRYPTO_EX_DATA ex_data;
        int references;
-       int depth;              /* how deep to look (still unused) */
+       int depth;              /* how deep to look (still unused -- X509_STORE_CTX's depth is used) */
        }  X509_STORE;
 
 #define X509_STORE_set_depth(ctx,d)       ((ctx)->depth=(d))
@@ -191,7 +191,7 @@ struct x509_lookup_st
 /* This is a temporary used when processing cert chains.  Since the
  * gathering of the cert chain can take some time (and have to be
  * 'retried', this needs to be kept and passed around. */
-struct x509_store_state_st
+struct x509_store_state_st      /* X509_STORE_CTX */
        {
        X509_STORE *ctx;
        int current_method;     /* used when looking up certs */
@@ -214,6 +214,8 @@ struct x509_store_state_st
        CRYPTO_EX_DATA ex_data;
        };
 
+#define X509_STORE_CTX_set_depth(ctx,d)       ((ctx)->depth=(d))
+
 #define X509_STORE_CTX_set_app_data(ctx,data) \
        X509_STORE_CTX_set_ex_data(ctx,0,data)
 #define X509_STORE_CTX_get_app_data(ctx) \
index 6a3ad30969526b550f9cbe497c178562e36f9b94..b041341ba5bb09c8be61a0b973254bf00061ce10 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -394,6 +394,7 @@ struct ssl_ctx_st
 /**/   struct cert_st /* CERT */ *default_cert;
 /**/   int read_ahead;
 /**/   int verify_mode;
+/**/   int verify_depth;
 /**/   unsigned int sid_ctx_length;
 /**/   unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
 /**/   int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx);
@@ -573,6 +574,7 @@ struct ssl_st
        /* Used in SSL2 and SSL3 */
        int verify_mode;        /* 0 don't care about verify failure.
                                 * 1 fail if verify fails */
+       int verify_depth;
        int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */
        void (*info_callback)(); /* optional informational callback */
 
@@ -851,9 +853,11 @@ BIO *      SSL_get_wbio(SSL *s);
 int    SSL_set_cipher_list(SSL *s, char *str);
 void   SSL_set_read_ahead(SSL *s, int yes);
 int    SSL_get_verify_mode(SSL *s);
+int    SSL_get_verify_depth(SSL *s);
 int    (*SSL_get_verify_callback(SSL *s))(int,X509_STORE_CTX *);
 void   SSL_set_verify(SSL *s, int mode,
                       int (*callback)(int ok,X509_STORE_CTX *ctx));
+void   SSL_set_verify_depth(SSL *s, int depth);
 #ifndef NO_RSA
 int    SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
 #endif
@@ -912,9 +916,11 @@ X509 *     SSL_get_peer_certificate(SSL *s);
 STACK_OF(X509) *SSL_get_peer_cert_chain(SSL *s);
 
 int SSL_CTX_get_verify_mode(SSL_CTX *ctx);
+int SSL_CTX_get_verify_depth(SSL_CTX *ctx);
 int (*SSL_CTX_get_verify_callback(SSL_CTX *ctx))(int,X509_STORE_CTX *);
 void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
                        int (*callback)(int, X509_STORE_CTX *));
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
 void SSL_CTX_set_cert_verify_cb(SSL_CTX *ctx, int (*cb)(),char *arg);
 #ifndef NO_RSA
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
index 88cc5fc21a33ab51ba847e6d075de2ea1ca095c3..91494dffb695fa03cebc293f37c8553796562cc0 100644 (file)
@@ -185,6 +185,8 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
 
        x=sk_X509_value(sk,0);
        X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk);
+       if (SSL_get_verify_depth(s) >= 0)
+               X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
        X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),
                (char *)s);
 
index 831768351c1264482a11a4f073f9bc95c682e9ca..945dab1cff786c86c57bdfc326057fd673bc2e35 100644 (file)
@@ -189,6 +189,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->sid_ctx_length=ctx->sid_ctx_length;
        memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
        s->verify_mode=ctx->verify_mode;
+       s->verify_depth=ctx->verify_depth;
        s->verify_callback=ctx->default_verify_callback;
        CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
        s->ctx=ctx;
@@ -422,6 +423,11 @@ int SSL_get_verify_mode(SSL *s)
        return(s->verify_mode);
        }
 
+int SSL_get_verify_depth(SSL *s)
+       {
+       return(s->verify_depth);
+       }
+
 int (*SSL_get_verify_callback(SSL *s))(int,X509_STORE_CTX *)
        {
        return(s->verify_callback);
@@ -432,6 +438,11 @@ int SSL_CTX_get_verify_mode(SSL_CTX *ctx)
        return(ctx->verify_mode);
        }
 
+int SSL_CTX_get_verify_depth(SSL_CTX *ctx)
+       {
+       return(ctx->verify_depth);
+       }
+
 int (*SSL_CTX_get_verify_callback(SSL_CTX *ctx))(int,X509_STORE_CTX *)
        {
        return(ctx->default_verify_callback);
@@ -445,6 +456,11 @@ void SSL_set_verify(SSL *s,int mode,
                s->verify_callback=callback;
        }
 
+void SSL_set_verify_depth(SSL *s,int depth)
+       {
+       s->verify_depth=depth;
+       }
+
 void SSL_set_read_ahead(SSL *s,int yes)
        {
        s->read_ahead=yes;
@@ -961,6 +977,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
 
        ret->read_ahead=0;
        ret->verify_mode=SSL_VERIFY_NONE;
+       ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
        ret->default_verify_callback=NULL;
        if ((ret->default_cert=ssl_cert_new()) == NULL)
                goto err;
@@ -1079,6 +1096,11 @@ void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*cb)(int, X509_STORE_CTX *))
        X509_STORE_set_verify_cb_func(ctx->cert_store,cb);
        }
 
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth)
+       {
+       ctx->verify_depth=depth;
+       }
+
 /* Need default_cert to check for callbacks, for now (see comment in CERT
    strucure)
 */
@@ -1463,6 +1485,7 @@ SSL *SSL_dup(SSL *s)
        SSL_set_read_ahead(ret,SSL_get_read_ahead(s));
        SSL_set_verify(ret,SSL_get_verify_mode(s),
                SSL_get_verify_callback(s));
+       SSL_set_verify_depth(ret,SSL_get_verify_depth(s));
 
        SSL_set_info_callback(ret,SSL_get_info_callback(s));