From 13938acecae8f1b455812d0388e2891abd1c096d Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 29 Nov 1999 01:09:25 +0000 Subject: Add part of chain verify SSL support code: not complete or doing anything 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. --- crypto/x509/Makefile.ssl | 31 +++++++++++++++++----- crypto/x509/x509.h | 5 +++- crypto/x509/x509_err.c | 3 ++- crypto/x509/x509_lu.c | 4 +-- crypto/x509/x509_v3.c | 22 ++++++++++++++++ crypto/x509/x509_vfy.c | 67 ++++++++++++++++++++++++++++++++++-------------- crypto/x509/x509_vfy.h | 11 ++++---- 7 files changed, 109 insertions(+), 34 deletions(-) (limited to 'crypto/x509') diff --git a/crypto/x509/Makefile.ssl b/crypto/x509/Makefile.ssl index db2aa5057d..346ffb2895 100644 --- a/crypto/x509/Makefile.ssl +++ b/crypto/x509/Makefile.ssl @@ -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 diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index 534c3d69f7..ed95058a74 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -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 diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c index acaa99ffae..6c85ddb84d 100644 --- a/crypto/x509/x509_err.c +++ b/crypto/x509/x509_err.c @@ -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"}, diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 837b81f154..95ee24b958 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -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; diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c index 5721f78510..100b08773c 100644 --- a/crypto/x509/x509_v3.c +++ b/crypto/x509/x509_v3.c @@ -63,6 +63,7 @@ #include #include #include +#include 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; +} diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 75ab96e506..11f462f461 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -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) diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h index 5e197040fb..822d9c7ea6 100644 --- a/crypto/x509/x509_vfy.h +++ b/crypto/x509/x509_vfy.h @@ -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 } -- cgit v1.2.3