mirror of
https://github.com/openssl/openssl.git
synced 2025-04-12 20:30:52 +08:00
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.
This commit is contained in:
parent
51630a3706
commit
13938aceca
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"},
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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)
|
||||
|
128
doc/man/verify.pod
Normal file
128
doc/man/verify.pod
Normal file
@ -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
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user