Add part of chain verify SSL support code: not complete or doing anything
authorDr. Stephen Henson <steve@openssl.org>
Mon, 29 Nov 1999 01:09:25 +0000 (01:09 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 29 Nov 1999 01:09:25 +0000 (01:09 +0000)
yet.

Add a function X509_STORE_CTX_purpose_inherit() which implements the logic
of "inheriting" purpose and trust from a parent structure and using a default:
this will be used in the SSL code and possibly future S/MIME.

Partial documentation of the 'verify' utility. Still need to document how all
the extension checking works and the various error messages.

18 files changed:
apps/verify.c
apps/x509.c
crypto/x509/Makefile.ssl
crypto/x509/x509.h
crypto/x509/x509_err.c
crypto/x509/x509_lu.c
crypto/x509/x509_v3.c
crypto/x509/x509_vfy.c
crypto/x509/x509_vfy.h
crypto/x509v3/v3_purp.c
crypto/x509v3/x509v3.h
doc/man/dsa.pod
doc/man/rsa.pod
doc/man/verify.pod [new file with mode: 0644]
doc/man/x509.pod
ssl/ssl.h
ssl/ssl_lib.c
util/libeay.num

index 8a03e0f..f9281a6 100644 (file)
@@ -84,9 +84,7 @@ int MAIN(int argc, char **argv)
        X509_STORE *cert_ctx=NULL;
        X509_LOOKUP *lookup=NULL;
 
-       X509_PURPOSE_add_standard();
-       X509_TRUST_add_standard();
-       X509V3_add_standard_extensions();
+       X509_init();
        cert_ctx=X509_STORE_new();
        if (cert_ctx == NULL) goto end;
        X509_STORE_set_verify_cb_func(cert_ctx,cb);
@@ -198,9 +196,7 @@ end:
        }
        if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
        sk_X509_pop_free(untrusted, X509_free);
-       X509V3_EXT_cleanup();
-       X509_PURPOSE_cleanup();
-       X509_TRUST_cleanup();
+       X509_cleanup();
        EXIT(ret);
        }
 
@@ -246,7 +242,7 @@ static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, int purpos
                goto end;
                }
        X509_STORE_CTX_init(csc,ctx,x,uchain);
-       if(purpose >= 0) X509_STORE_CTX_chain_purpose(csc, purpose);
+       if(purpose >= 0) X509_STORE_CTX_set_purpose(csc, purpose);
        i=X509_verify_cert(csc);
        X509_STORE_CTX_free(csc);
 
index 8689608..caf5946 100644 (file)
@@ -384,8 +384,7 @@ bad:
                app_RAND_load_file(NULL, bio_err, 0);
 
        ERR_load_crypto_strings();
-       X509V3_add_standard_extensions();
-       X509_PURPOSE_add_standard();
+       X509_init();
 
        if (!X509_STORE_set_default_paths(ctx))
                {
@@ -871,8 +870,7 @@ end:
        EVP_PKEY_free(Upkey);
        EVP_PKEY_free(CApkey);
        X509_REQ_free(rq);
-       X509V3_EXT_cleanup();
-       X509_PURPOSE_cleanup();
+       X509_cleanup();
        EXIT(ret);
        }
 
index db2aa50..346ffb2 100644 (file)
@@ -294,6 +294,24 @@ x509_set.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 x509_set.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 x509_set.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 x509_set.o: ../cryptlib.h
+x509_trs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+x509_trs.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+x509_trs.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+x509_trs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_trs.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+x509_trs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+x509_trs.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+x509_trs.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+x509_trs.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+x509_trs.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+x509_trs.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_trs.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
+x509_trs.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+x509_trs.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
+x509_trs.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+x509_trs.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_trs.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x509_trs.o: ../../include/openssl/x509v3.h ../cryptlib.h
 x509_txt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 x509_txt.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
 x509_txt.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
@@ -315,11 +333,12 @@ x509_txt.o: ../cryptlib.h
 x509_v3.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 x509_v3.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
 x509_v3.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
-x509_v3.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
-x509_v3.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
-x509_v3.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
-x509_v3.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_v3.o: ../../include/openssl/idea.h ../../include/openssl/md2.h
+x509_v3.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_v3.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+x509_v3.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+x509_v3.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+x509_v3.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+x509_v3.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
 x509_v3.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
 x509_v3.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509_v3.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
@@ -328,7 +347,7 @@ x509_v3.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
 x509_v3.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 x509_v3.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 x509_v3.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-x509_v3.o: ../cryptlib.h
+x509_v3.o: ../../include/openssl/x509v3.h ../cryptlib.h
 x509_vfy.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 x509_vfy.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
 x509_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
index 534c3d6..ed95058 100644 (file)
@@ -1015,6 +1015,8 @@ int               X509_EXTENSION_set_data(X509_EXTENSION *ex,
 ASN1_OBJECT *  X509_EXTENSION_get_object(X509_EXTENSION *ex);
 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
 int            X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+void           X509_init(void);
+void           X509_cleanup(void);
 
 int            X509_verify_cert(X509_STORE_CTX *ctx);
 
@@ -1098,9 +1100,9 @@ int X509_TRUST_get_trust(X509_TRUST *xp);
 #define X509_F_X509_REQ_PRINT                           121
 #define X509_F_X509_REQ_PRINT_FP                        122
 #define X509_F_X509_REQ_TO_X509                                 123
-#define X509_F_X509_SET_PURPOSE_AND_TRUST               134
 #define X509_F_X509_STORE_ADD_CERT                      124
 #define X509_F_X509_STORE_ADD_CRL                       125
+#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT           134
 #define X509_F_X509_TO_X509_REQ                                 126
 #define X509_F_X509_TRUST_ADD                           133
 #define X509_F_X509_VERIFY_CERT                                 127
@@ -1123,6 +1125,7 @@ int X509_TRUST_get_trust(X509_TRUST *xp);
 #define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY           108
 #define X509_R_UNKNOWN_KEY_TYPE                                 117
 #define X509_R_UNKNOWN_NID                              109
+#define X509_R_UNKNOWN_PURPOSE_ID                       121
 #define X509_R_UNKNOWN_TRUST_ID                                 120
 #define X509_R_UNSUPPORTED_ALGORITHM                    111
 #define X509_R_WRONG_LOOKUP_TYPE                        112
index acaa99f..6c85ddb 100644 (file)
@@ -91,9 +91,9 @@ static ERR_STRING_DATA X509_str_functs[]=
 {ERR_PACK(0,X509_F_X509_REQ_PRINT,0),  "X509_REQ_print"},
 {ERR_PACK(0,X509_F_X509_REQ_PRINT_FP,0),       "X509_REQ_print_fp"},
 {ERR_PACK(0,X509_F_X509_REQ_TO_X509,0),        "X509_REQ_to_X509"},
-{ERR_PACK(0,X509_F_X509_SET_PURPOSE_AND_TRUST,0),      "X509_set_purpose_and_trust"},
 {ERR_PACK(0,X509_F_X509_STORE_ADD_CERT,0),     "X509_STORE_add_cert"},
 {ERR_PACK(0,X509_F_X509_STORE_ADD_CRL,0),      "X509_STORE_add_crl"},
+{ERR_PACK(0,X509_F_X509_STORE_CTX_PURPOSE_INHERIT,0),  "X509_STORE_CTX_purpose_inherit"},
 {ERR_PACK(0,X509_F_X509_TO_X509_REQ,0),        "X509_to_X509_REQ"},
 {ERR_PACK(0,X509_F_X509_TRUST_ADD,0),  "X509_TRUST_add"},
 {ERR_PACK(0,X509_F_X509_VERIFY_CERT,0),        "X509_verify_cert"},
@@ -119,6 +119,7 @@ static ERR_STRING_DATA X509_str_reasons[]=
 {X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY   ,"unable to get certs public key"},
 {X509_R_UNKNOWN_KEY_TYPE                 ,"unknown key type"},
 {X509_R_UNKNOWN_NID                      ,"unknown nid"},
+{X509_R_UNKNOWN_PURPOSE_ID               ,"unknown purpose id"},
 {X509_R_UNKNOWN_TRUST_ID                 ,"unknown trust id"},
 {X509_R_UNSUPPORTED_ALGORITHM            ,"unsupported algorithm"},
 {X509_R_WRONG_LOOKUP_TYPE                ,"wrong lookup type"},
index 837b81f..95ee24b 100644 (file)
@@ -403,8 +403,8 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
        ctx->cert=x509;
        ctx->untrusted=chain;
        ctx->last_untrusted=0;
-       ctx->chain_purpose=0;
-       ctx->trust_purpose=0;
+       ctx->purpose=0;
+       ctx->trust=0;
        ctx->valid=0;
        ctx->chain=NULL;
        ctx->depth=9;
index 5721f78..100b087 100644 (file)
@@ -63,6 +63,7 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
        {
@@ -264,3 +265,24 @@ int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
        if (ex == NULL) return(0);
        return(ex->critical);
        }
+
+/* Initialisation routine: used to initialise the X509 and X509v3 tables */
+
+static int init_done = 0;
+
+void X509_init(void)
+{
+       if(init_done) return;
+       X509V3_add_standard_extensions();
+       X509_PURPOSE_add_standard();
+       X509_TRUST_add_standard();
+       init_done = 1;
+}
+
+void X509_cleanup(void)
+{
+       X509V3_EXT_cleanup();
+       X509_PURPOSE_cleanup();
+       X509_TRUST_cleanup();
+       init_done = 0;
+}
index 75ab96e..11f462f 100644 (file)
@@ -294,13 +294,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
                }
 
        /* We have the chain complete: now we need to check its purpose */
-       if(ctx->chain_purpose > 0) ok = check_chain_purpose(ctx);
+       if(ctx->purpose > 0) ok = check_chain_purpose(ctx);
 
        if(!ok) goto end;
 
        /* The chain extensions are OK: check trust */
 
-       if(ctx->trust_purpose > 0) ok = check_trust(ctx);
+       if(ctx->trust > 0) ok = check_trust(ctx);
 
        if(!ok) goto end;
 
@@ -339,7 +339,7 @@ static int check_chain_purpose(X509_STORE_CTX *ctx)
        /* Check all untrusted certificates */
        for(i = 0; i < ctx->last_untrusted; i++) {
                x = sk_X509_value(ctx->chain, i);
-               if(!X509_check_purpose(x, ctx->chain_purpose, i)) {
+               if(!X509_check_purpose(x, ctx->purpose, i)) {
                        if(i) ctx->error = X509_V_ERR_INVALID_CA;
                        else ctx->error = X509_V_ERR_INVALID_PURPOSE;
                        ctx->error_depth = i;
@@ -376,7 +376,7 @@ static int check_trust(X509_STORE_CTX *ctx)
 /* For now just check the last certificate in the chain */
        i = sk_X509_num(ctx->chain) - 1;
        x = sk_X509_value(ctx->chain, i);
-       ok = X509_check_trust(x, ctx->trust_purpose, 0);
+       ok = X509_check_trust(x, ctx->trust, 0);
        if(ok == X509_TRUST_TRUSTED) return 1;
        ctx->error_depth = sk_X509_num(ctx->chain) - 1;
        ctx->current_cert = x;
@@ -727,33 +727,62 @@ void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
        ctx->untrusted=sk;
        }
 
-int X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose)
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
        {
-               return X509_set_purpose_and_trust(purpose,
-                               &ctx->chain_purpose, &ctx->trust_purpose);
+       return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
        }
 
-void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose)
+void X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
        {
-       ctx->trust_purpose = purpose;
+       ctx->trust = trust;
        }
 
-int X509_set_purpose_and_trust(int id, int *purp, int *trust)
+/* This function is used to set the X509_STORE_CTX purpose and trust
+ * values. This is intended to be used when another structure has its
+ * own trust and purpose values which (if set) will be inherited by
+ * the ctx. If they aren't set then we will usually have a default
+ * purpose in mind which should then be used to set the trust value.
+ * An example of this is SSL use: an SSL structure will have its own
+ * purpose and trust settings which the application can set: if they
+ * aren't set then we use the default of SSL client/server.
+ */
+
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+                               int purpose, int trust)
 {
-       X509_PURPOSE *ptmp;
        int idx;
-       idx = X509_PURPOSE_get_by_id(id);
-       if(idx == -1) {
-               X509err(X509_F_X509_SET_PURPOSE_AND_TRUST,
-                                       X509_R_UNKNOWN_TRUST_ID);
-               return 0;
+       /* If purpose not set use default */
+       if(!purpose) purpose = def_purpose;
+       /* If we have a purpose then check it is valid */
+       if(purpose) {
+               idx = X509_PURPOSE_get_by_id(purpose);
+               if(idx == -1) {
+                       X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+                                               X509_R_UNKNOWN_PURPOSE_ID);
+                       return 0;
+               }
+               /* If trust not set then get from purpose default */
+               if(!trust) {
+                       X509_PURPOSE *ptmp;
+                       ptmp = X509_PURPOSE_iget(idx);
+                       trust = ptmp->trust;
+               }
        }
-       ptmp = X509_PURPOSE_iget(idx);
-       if(purp) *purp = id;
-       if(trust) *trust = ptmp->trust_id;
+       if(trust) {
+               idx = X509_TRUST_get_by_id(trust);
+               if(idx == -1) {
+                       X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+                                               X509_R_UNKNOWN_TRUST_ID);
+                       return 0;
+               }
+       }
+
+       if(purpose) ctx->purpose = purpose;
+       if(trust) ctx->trust = trust;
        return 1;
 }
 
+
 IMPLEMENT_STACK_OF(X509)
 IMPLEMENT_ASN1_SET_OF(X509)
 
index 5e19704..822d9c7 100644 (file)
@@ -202,8 +202,8 @@ struct x509_store_state_st      /* X509_STORE_CTX */
        /* The following are set by the caller */
        X509 *cert;             /* The cert to check */
        STACK_OF(X509) *untrusted;      /* chain of X509s - untrusted - passed in */
-       int chain_purpose;              /* purpose to check untrusted certificates */
-       int trust_purpose;              /* trust setting to check */
+       int purpose;            /* purpose to check untrusted certificates */
+       int trust;              /* trust setting to check */
 
        /* The following is built up */
        int depth;              /* how far to go looking up certs */
@@ -349,9 +349,10 @@ X509 *     X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
 void   X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
 void   X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
-int X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose);
-void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose);
-int X509_set_purpose_and_trust(int id, int *purp, int *trust);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+void X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+                               int purpose, int trust);
 
 #ifdef  __cplusplus
 }
index 0eb20d3..e350c81 100644 (file)
@@ -91,7 +91,7 @@ static STACK_OF(X509_PURPOSE) *xptable = NULL;
 
 static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b)
 {
-       return (*a)->purpose_id - (*b)->purpose_id;
+       return (*a)->purpose - (*b)->purpose;
 }
 
 int X509_check_purpose(X509 *x, int id, int ca)
@@ -100,6 +100,7 @@ int X509_check_purpose(X509 *x, int id, int ca)
        X509_PURPOSE *pt;
        if(!(x->ex_flags & EXFLAG_SET)) {
                CRYPTO_w_lock(CRYPTO_LOCK_X509);
+               X509_init();
                x509v3_cache_extensions(x);
                CRYPTO_w_unlock(CRYPTO_LOCK_X509);
        }
@@ -126,16 +127,16 @@ int X509_PURPOSE_get_by_sname(char *sname)
        X509_PURPOSE *xptmp;
        for(i = 0; i < sk_X509_PURPOSE_num(xptable); i++) {
                xptmp = sk_X509_PURPOSE_value(xptable, i);
-               if(!strcmp(xptmp->purpose_sname, sname)) return i;
+               if(!strcmp(xptmp->sname, sname)) return i;
        }
        return -1;
 }
 
 
-int X509_PURPOSE_get_by_id(int id)
+int X509_PURPOSE_get_by_id(int purpose)
 {
        X509_PURPOSE tmp;
-       tmp.purpose_id = id;
+       tmp.purpose = purpose;
        if(!xptable) return -1;
        return sk_X509_PURPOSE_find(xptable, &tmp);
 }
@@ -153,7 +154,7 @@ int X509_PURPOSE_add(X509_PURPOSE *xp)
                        }
                }
                        
-       idx = X509_PURPOSE_get_by_id(xp->purpose_id);
+       idx = X509_PURPOSE_get_by_id(xp->purpose);
        if(idx != -1) {
                xptable_free(sk_X509_PURPOSE_value(xptable, idx));
                sk_X509_PURPOSE_set(xptable, idx, xp);
@@ -169,11 +170,11 @@ int X509_PURPOSE_add(X509_PURPOSE *xp)
 static void xptable_free(X509_PURPOSE *p)
        {
        if(!p) return;
-       if (p->purpose_flags & X509_PURPOSE_DYNAMIC) 
+       if (p->flags & X509_PURPOSE_DYNAMIC) 
                {
-               if (p->purpose_flags & X509_PURPOSE_DYNAMIC_NAME) {
-                       Free(p->purpose_name);
-                       Free(p->purpose_sname);
+               if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
+                       Free(p->name);
+                       Free(p->sname);
                }
                Free(p);
                }
@@ -188,28 +189,27 @@ void X509_PURPOSE_cleanup(void)
 void X509_PURPOSE_add_standard(void)
 {
        X509_PURPOSE *xp;
-       for(xp = xstandard; xp->purpose_name; xp++)
-               X509_PURPOSE_add(xp);
+       for(xp = xstandard; xp->name; xp++) X509_PURPOSE_add(xp);
 }
 
 int X509_PURPOSE_get_id(X509_PURPOSE *xp)
 {
-       return xp->purpose_id;
+       return xp->purpose;
 }
 
 char *X509_PURPOSE_iget_name(X509_PURPOSE *xp)
 {
-       return xp->purpose_name;
+       return xp->name;
 }
 
 char *X509_PURPOSE_iget_sname(X509_PURPOSE *xp)
 {
-       return xp->purpose_sname;
+       return xp->sname;
 }
 
 int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
 {
-       return xp->trust_id;
+       return xp->trust;
 }
 
 static void x509v3_cache_extensions(X509 *x)
index 5a97e09..bee56ab 100644 (file)
@@ -329,12 +329,12 @@ DECLARE_ASN1_SET_OF(POLICYINFO)
 #define X509_PURPOSE_DYNAMIC_NAME      0x2
 
 typedef struct x509_purpose_st {
-       int purpose_id;
-       int trust_id;           /* Default trust ID */
-       int purpose_flags;
+       int purpose;
+       int trust;              /* Default trust ID */
+       int flags;
        int (*check_purpose)(struct x509_purpose_st *, X509 *, int);
-       char *purpose_name;
-       char *purpose_sname;
+       char *name;
+       char *sname;
        void *usr_data;
 } X509_PURPOSE;
 
index 4187ef4..1235e55 100644 (file)
@@ -40,11 +40,12 @@ applications should use the more secure PKCS#8 format using the B<pkcs8>
 This specifies the input format. The B<DER> option with a private key uses
 an ASN1 DER encoded form of an ASN.1 SEQUENCE consisting of the values of
 version (currently zero), p, q, g, the public and private key components
-respectively as ASN.1 INTEGERs. When used with a public key it outputs a
-SEQUENCE of the public key component, p, q and g respectively.
+respectively as ASN.1 INTEGERs. When used with a public key it uses a
+SubjectPublicKeyInfo structure: it is an error if the key is not DSA.
 
 The B<PEM> form is the default format: it consists of the B<DER> format base64
-encoded with additional header and footer lines.
+encoded with additional header and footer lines. In the case of a private key
+PKCS#8 format is also accepted.
 
 =item B<-outform DER|PEM>
 
index 9834eb3..570832a 100644 (file)
@@ -41,11 +41,12 @@ utility.
 =item B<-inform DER|NET|PEM>
 
 This specifies the input format. The B<DER> option uses an ASN1 DER encoded
-form compatible with the PKCS#1 RSAPrivateKey or RSAPublicKey format. The B<PEM>
-form is the default format: it consists of the B<DER> format base64 encoded with
-additional header and footer lines. The B<NET> form is a format compatible
-with older Netscape servers and MS IIS, this uses unsalted RC4 for its
-encryption It is not very secure and so should only be used when necessary.
+form compatible with the PKCS#1 RSAPrivateKey or SubjectPublicKeyInfo format.
+The B<PEM> form is the default format: it consists of the B<DER> format base64
+encoded with additional header and footer lines. On input PKCS#8 format private
+keys are also accepted.The B<NET> form is a format compatible with older Netscape
+servers and MS IIS, this uses unsalted RC4 for its encryption. It is not very
+secure and so should only be used when necessary.
 
 =item B<-outform DER|NET|PEM>
 
@@ -152,11 +153,6 @@ To just output the public part of a private key:
 
 C<openssl rsa -in key.pem -pubout -out pubkey.pem>
 
-=head1 CAVEATS
-
-It should be possible to read or produce PKCS#8 format encrypted RSA keys:
-at present it isn't.
-
 =head1 SEE ALSO
 
 pkcs8(1), dsa(1), genrsa(1), gendsa(1)
diff --git a/doc/man/verify.pod b/doc/man/verify.pod
new file mode 100644 (file)
index 0000000..36c4710
--- /dev/null
@@ -0,0 +1,128 @@
+=pod
+
+=head1 NAME
+
+pkcs7 - PKCS#7 utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<verify>
+[B<-CApath directory>]
+[B<-CAfile file>]
+[B<-purpose purpose>]
+[B<-untrusted file>]
+[B<-help>]
+[B<-verbose>]
+[B<->]
+[certificates]
+
+
+=head1 DESCRIPTION
+
+The B<verify> command verifies certificate chains.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-CApath directory>
+
+A directory of trusted certificates. The certificates should have names
+of the form: hash.0 or have symbolic links to them of this
+form ("hash" is the hashed certificate subject name: see the B<-hash> option
+of the B<x509> utility). Under Unix the B<c_rehash> script will automatically
+create symbolic links to a directory of certificates.
+
+=item B<-CAfile file>
+
+A file of trusted certificates. The file should contain multiple certificates
+in PEM format concatenated together.
+
+=item B<-untrusted file>
+
+A file of untrusted certificates. The file should contain multiple certificates
+
+=item B<-purpose purpose>
+
+the intended use for the certificate. Without this option no chain verification
+will be done. Currently accepted uses are B<sslclient>, B<sslserver>,
+B<nssslserver>, B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION>
+section for more information.
+
+=item B<-help>
+
+prints out a usage message.
+
+=item B<-verbose>
+
+print extra information about the operations being performed.
+
+=item B<->
+
+marks the last option. All arguments following this are assumed to be
+certificate files.
+
+
+=item B<certificates>
+
+one or more certificates to verify. If no certificate filenames are included
+then an attempt is made to read a certificate from standard input. They should
+all be in PEM format.
+
+
+=back
+
+=head1 VERIFY OPERATION
+
+The B<verify> program uses the same functions as the internal SSL and S/MIME
+verification, therefore this description applies to these verify operations
+too.
+
+There is one crucial difference between the verify operations performed
+by the B<verify> program: wherever possible an attempt is made to continue
+after an error whereas normally the verify operation would halt on the
+first error. This allows all the problems with a certificate chain to be
+determined.
+
+The verify operation consists of a number of separate steps.
+
+Firstly a certificate chain is built up starting from the supplied certificate
+and ending in the root CA. It is an error if the whole chain cannot be built
+up. The chain is built up by looking up a certificate whose subject name
+matches the issuer name of the current certificate. If a certificate is found
+whose subject and issuer names are identical it is assumed to be the root CA.
+The lookup first looks in the list of untrusted certificates and if no match
+is found the remaining lookups are from the trusted certficates. The root CA
+is always looked up in the trusted certificate list: if the certificate to
+verify is a root certificate then an exact match must be found in the trusted
+list.
+
+The second operation is to check every untrusted certificate's extensions for
+consistency with the supplied purpose. If the B<-purpose> option is not included
+then no checks are done. The supplied or "leaf" certificate must have extensions
+compatible with the supplied purpose and all other certificates must also be valid
+CA certificates. The precise extensions required are described in more detail in
+the B<CERTIFICATE EXTENSIONS> section.
+
+The third operation is to check the trust settings on the root CA. The root
+CA should be trusted for the supplied purpose. For compatability with previous
+versions of SSLeay and OpenSSL a certificate with no trust settings is considered
+to be valid for all purposes. 
+
+The final operation is to check the validity of the certificate chain. The validity
+period is checked against the current system time and the notBefore and notAfter
+dates in the certificate. The certificate signatures are also checked at this
+point.
+
+If all operations complete successfully then certificate is considered valid. If
+any operation fails then the certificate is not valid.
+
+=head1 CERTIFICATE EXTENSIONS
+
+...to be added...
+
+=head1 SEE ALSO
+
+x509(1)
+
+=cut
index 9f8c947..135b6f7 100644 (file)
@@ -172,20 +172,17 @@ must be "trusted". By default a trusted certificate must be stored
 locally and must be a root CA: any certificate chain ending in this CA
 is then usable for any purpose.
 
-Adding trust settings modifies this behaviour: if a certificate is being 
-verified and one of the certificate chain is marked as trusted for that
-specific purpose then the verify succeeds without looking up any more
-certificates. Similarly if the use is prohibited then the certificate
-is automatically rejected. If a purpose is neither permitted nor prohibited
-then the certificate extensions are checked for consistency with the required
-purpose and the process continues.
-
-If a root CA is reached then it must be marked as trusted for the required
-purpose or the verify fails.
+Trust settings currently are only used with a root CA. They allow a finer
+control over the purposes the root CA can be used for. For example a CA
+may be trusted for SSL client but not SSL server use.
 
 See the description of the B<verify> utility for more information on the
 meaning of trust settings.
 
+Future versions of OpenSSL will recognise trust settings on any
+certificate: not just root CAs.
+
+
 =over 4
 
 =item B<-trustout>
@@ -211,13 +208,13 @@ clears all the permitted or trusted uses of the certificate.
 
 =item B<-clrreject>
 
-clears all the prohibited or untrusted uses of the certificate.
+clears all the prohibited or rejected uses of the certificate.
 
 =item B<-addtrust arg>
 
 adds a trusted certificate use. Currently acceptable values
-are all (any purpose), sslclient (SSL client use), sslserver
-(SSL server use) email (S/MIME email) and objsign (Object signing).
+are B<all> (any purpose), B<sslclient> (SSL client use), B<sslserver>
+(SSL server use) B<email> (S/MIME email) and B<objsign> (Object signing).
 
 =item B<-addreject arg>
 
index f888530..1b39f0d 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -429,6 +429,9 @@ struct ssl_ctx_st
 /**/   unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
 /**/   int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx);
 
+       int purpose;            /* Purpose setting */
+       int trust;              /* Trust setting */
+
        /* Default password callback. */
 /**/   pem_password_cb *default_passwd_callback;
 
@@ -575,6 +578,9 @@ struct ssl_st
        int read_ahead;         /* Read as many input bytes as possible */
        int hit;                /* reusing a previous session */
 
+       int purpose;            /* Purpose setting */
+       int trust;              /* Trust setting */
+
        /* crypto */
        STACK_OF(SSL_CIPHER) *cipher_list;
        STACK_OF(SSL_CIPHER) *cipher_list_by_id;
index e192fc4..9dd6860 100644 (file)
@@ -201,6 +201,8 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->verify_mode=ctx->verify_mode;
        s->verify_depth=ctx->verify_depth;
        s->verify_callback=ctx->default_verify_callback;
+       s->purpose = ctx->purpose;
+       s->trust = ctx->trust;
        CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
        s->ctx=ctx;
 
index 811f6ec..a14719d 100755 (executable)
@@ -2076,13 +2076,48 @@ sk_ACCESS_DESCRIPTION_delete_ptr        2100
 sk_ACCESS_DESCRIPTION_insert            2101
 sk_ACCESS_DESCRIPTION_sort              2102
 sk_ACCESS_DESCRIPTION_set_cmp_func      2103
-X509_STORE_CTX_chain_purpose            2104
-X509_STORE_CTX_free                     2105
-X509_STORE_CTX_trust_purpose            2106
-X509_STORE_CTX_new                      2107
-X509_PURPOSE_iget                       2108
-X509_PURPOSE_get_by_sname               2109
-X509_PURPOSE_get_id                     2110
-X509_PURPOSE_get_trust                  2111
-X509_PURPOSE_get_count                  2112
-X509_PURPOSE_iget_sname                 2113
+sk_X509_TRUST_pop                       2104
+X509_cleanup                            2105
+sk_X509_TRUST_set_cmp_func              2106
+X509_PURPOSE_get_by_sname               2107
+X509_STORE_CTX_free                     2108
+sk_X509_TRUST_pop_free                  2109
+X509_STORE_CTX_purpose_inherit          2110
+sk_X509_TRUST_push                      2111
+X509_PURPOSE_get_id                     2112
+sk_X509_TRUST_find                      2113
+X509_TRUST_get_id                       2114
+X509_TRUST_iget_name                    2115
+X509_TRUST_iget                         2116
+sk_X509_TRUST_unshift                   2117
+X509_PURPOSE_get_count                  2118
+X509_add_reject_object                  2119
+sk_X509_TRUST_new_null                  2120
+sk_X509_TRUST_new                       2121
+sk_X509_TRUST_delete_ptr                2122
+X509_PURPOSE_iget_sname                 2123
+X509_TRUST_get_count                    2124
+X509_reject_set_bit_asc                 2125
+X509_PURPOSE_iget                       2126
+sk_X509_TRUST_free                      2127
+sk_X509_TRUST_num                       2128
+X509_init                               2129
+X509_TRUST_add                          2130
+X509_TRUST_add_standard                 2131
+sk_X509_TRUST_zero                      2132
+sk_X509_TRUST_shift                     2133
+X509_TRUST_cleanup                      2134
+sk_X509_TRUST_set                       2135
+X509_TRUST_get_by_id                    2136
+X509_PURPOSE_get_trust                  2137
+X509_STORE_CTX_set_trust                2138
+X509_STORE_CTX_new                      2139
+sk_X509_TRUST_value                     2140
+X509_TRUST_get_trust                    2141
+X509_STORE_CTX_set_purpose              2142
+sk_X509_TRUST_dup                       2143
+sk_X509_TRUST_insert                    2144
+X509_check_trust                        2145
+sk_X509_TRUST_sort                      2146
+X509_reject_set_bit                     2147
+sk_X509_TRUST_delete                    2148