提交 13938ace 编写于 作者: D Dr. Stephen Henson

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.
上级 51630a37
......@@ -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)
......
=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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册