New options to the -verify program which can be used for chain verification.

Extend the X509_PURPOSE structure to include shortnames for purposed and default
trust ids.

Still need some extendable trust checking code and integration with the SSL and
S/MIME code.
This commit is contained in:
Dr. Stephen Henson 1999-11-26 00:27:07 +00:00
parent 1126239111
commit d4cec6a13d
17 changed files with 290 additions and 112 deletions

16
CHANGES
View File

@ -7,15 +7,21 @@
*) Very preliminary certificate chain verify code. Currently just tests
the untrusted certificates for consistency with the verify purpose
(which is set when the X509_STORE_CTX structure is set up) and checks
the pathlength. Totally untested at present: needs some extra
functionality in the verify program first. There is a
NO_CHAIN_VERIFY compilation option to keep the old behaviour: this is
because when it is finally working it will reject chains with
invalid extensions whereas before it made no checks at all.
the pathlength. There is a NO_CHAIN_VERIFY compilation option to keep
the old behaviour: this is because when it is finally working it will
reject chains with invalid extensions whereas before it made no checks
at all.
Still needs some trust checking code.
Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
which should be used for version portability: especially since the
verify structure is likely to change more often now.
Two new options to the verify program: -untrusted allows a set of
untrusted certificates to be passed in and -purpose which sets the
intended purpose of the certificate. If a purpose is set then the
new chain verify code is used to check extension consistency.
[Steve Henson]
*) Support for the authority information access extension.

View File

@ -727,11 +727,12 @@ spkac.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h apps.h progs.h
verify.o: ../include/openssl/asn1.h ../include/openssl/bio.h
verify.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
verify.o: ../include/openssl/buffer.h ../include/openssl/cast.h
verify.o: ../include/openssl/crypto.h ../include/openssl/des.h
verify.o: ../include/openssl/dh.h ../include/openssl/dsa.h
verify.o: ../include/openssl/e_os.h ../include/openssl/e_os2.h
verify.o: ../include/openssl/err.h ../include/openssl/evp.h
verify.o: ../include/openssl/idea.h ../include/openssl/md2.h
verify.o: ../include/openssl/conf.h ../include/openssl/crypto.h
verify.o: ../include/openssl/des.h ../include/openssl/dh.h
verify.o: ../include/openssl/dsa.h ../include/openssl/e_os.h
verify.o: ../include/openssl/e_os2.h ../include/openssl/err.h
verify.o: ../include/openssl/evp.h ../include/openssl/idea.h
verify.o: ../include/openssl/lhash.h ../include/openssl/md2.h
verify.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
verify.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
verify.o: ../include/openssl/opensslv.h ../include/openssl/pem.h
@ -740,8 +741,8 @@ verify.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
verify.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h
verify.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
verify.o: ../include/openssl/sha.h ../include/openssl/stack.h
verify.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h apps.h
verify.o: progs.h
verify.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
verify.o: ../include/openssl/x509v3.h apps.h progs.h
version.o: ../include/openssl/asn1.h ../include/openssl/bio.h
version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
version.o: ../include/openssl/buffer.h ../include/openssl/cast.h

View File

@ -287,13 +287,14 @@ int MAIN(int argc, char **argv)
PKCS8_PRIV_KEY_INFO *p8;
PKCS7 *authsafe;
X509 *ucert = NULL;
STACK_OF(X509) *certs;
STACK_OF(X509) *certs=NULL;
char *catmp;
int i;
unsigned char keyid[EVP_MAX_MD_SIZE];
unsigned int keyidlen = 0;
key = PEM_read_bio_PrivateKey(inkey ? inkey : in, NULL, NULL, NULL);
if (!inkey) (void) BIO_reset(in);
else BIO_free(inkey);
if (!key) {
BIO_printf (bio_err, "Error loading private key\n");
ERR_print_errors(bio_err);
@ -364,7 +365,7 @@ int MAIN(int argc, char **argv)
PKCS12_add_friendlyname(bag, catmp, -1);
sk_push(bags, (char *)bag);
}
sk_X509_pop_free(certs, X509_free);
if (canames) sk_free(canames);
if(!noprompt &&

View File

@ -63,22 +63,29 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
#undef PROG
#define PROG verify_main
static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
static int check(X509_STORE *ctx,char *file);
static int check(X509_STORE *ctx,char *file, STACK_OF(X509)*other, int purpose);
static STACK_OF(X509) *load_untrusted(char *file);
static int v_verbose=0;
int MAIN(int argc, char **argv)
{
int i,ret=1;
int purpose = -1;
char *CApath=NULL,*CAfile=NULL;
char *untfile = NULL;
STACK_OF(X509) *untrusted = NULL;
X509_STORE *cert_ctx=NULL;
X509_LOOKUP *lookup=NULL;
X509_PURPOSE_add_standard();
X509V3_add_standard_extensions();
cert_ctx=X509_STORE_new();
if (cert_ctx == NULL) goto end;
X509_STORE_set_verify_cb_func(cert_ctx,cb);
@ -107,6 +114,24 @@ int MAIN(int argc, char **argv)
if (argc-- < 1) goto end;
CAfile= *(++argv);
}
else if (strcmp(*argv,"-purpose") == 0)
{
X509_PURPOSE *xptmp;
if (argc-- < 1) goto end;
i = X509_PURPOSE_get_by_sname(*(++argv));
if(i < 0)
{
BIO_printf(bio_err, "unrecognised purpose\n");
goto end;
}
xptmp = X509_PURPOSE_iget(i);
purpose = X509_PURPOSE_get_id(xptmp);
}
else if (strcmp(*argv,"-untrusted") == 0)
{
if (argc-- < 1) goto end;
untfile= *(++argv);
}
else if (strcmp(*argv,"-help") == 0)
goto end;
else if (strcmp(*argv,"-verbose") == 0)
@ -144,26 +169,45 @@ int MAIN(int argc, char **argv)
}
} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
ERR_clear_error();
if (argc < 1) check(cert_ctx,NULL);
if(untfile) {
if(!(untrusted = load_untrusted(untfile))) {
BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile);
ERR_print_errors(bio_err);
goto end;
}
}
if (argc < 1) check(cert_ctx, NULL, untrusted, purpose);
else
for (i=0; i<argc; i++)
check(cert_ctx,argv[i]);
check(cert_ctx,argv[i], untrusted, purpose);
ret=0;
end:
if (ret == 1)
if (ret == 1) {
BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] cert1 cert2 ...\n");
BIO_printf(bio_err,"recognised usages:\n");
for(i = 0; i < X509_PURPOSE_get_count(); i++) {
X509_PURPOSE *ptmp;
ptmp = X509_PURPOSE_iget(i);
BIO_printf(bio_err, "\t%-10s\t%s\n", X509_PURPOSE_iget_sname(ptmp),
X509_PURPOSE_iget_name(ptmp));
}
}
if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
sk_X509_pop_free(untrusted, X509_free);
X509V3_EXT_cleanup();
X509_PURPOSE_cleanup();
EXIT(ret);
}
static int check(X509_STORE *ctx, char *file)
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, int purpose)
{
X509 *x=NULL;
BIO *in=NULL;
int i=0,ret=0;
X509_STORE_CTX csc;
X509_STORE_CTX *csc;
in=BIO_new(BIO_s_file());
if (in == NULL)
@ -193,9 +237,16 @@ static int check(X509_STORE *ctx, char *file)
}
fprintf(stdout,"%s: ",(file == NULL)?"stdin":file);
X509_STORE_CTX_init(&csc,ctx,x,NULL);
i=X509_verify_cert(&csc);
X509_STORE_CTX_cleanup(&csc);
csc = X509_STORE_CTX_new();
if (csc == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
X509_STORE_CTX_init(csc,ctx,x,uchain);
if(purpose >= 0) X509_STORE_CTX_chain_purpose(csc, purpose);
i=X509_verify_cert(csc);
X509_STORE_CTX_free(csc);
ret=0;
end:
@ -212,6 +263,52 @@ end:
return(ret);
}
static STACK_OF(X509) *load_untrusted(char *certfile)
{
STACK_OF(X509_INFO) *sk=NULL;
STACK_OF(X509) *stack=NULL, *ret=NULL;
BIO *in=NULL;
X509_INFO *xi;
if(!(stack = sk_X509_new_null())) {
BIO_printf(bio_err,"memory allocation failure\n");
goto end;
}
if(!(in=BIO_new_file(certfile, "r"))) {
BIO_printf(bio_err,"error opening the file, %s\n",certfile);
goto end;
}
/* This loads from a file, a stack of x509/crl/pkey sets */
if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) {
BIO_printf(bio_err,"error reading the file, %s\n",certfile);
goto end;
}
/* scan over it and pull out the certs */
while (sk_X509_INFO_num(sk))
{
xi=sk_X509_INFO_shift(sk);
if (xi->x509 != NULL)
{
sk_X509_push(stack,xi->x509);
xi->x509=NULL;
}
X509_INFO_free(xi);
}
if(!sk_X509_num(stack)) {
BIO_printf(bio_err,"no certificates in file, %s\n",certfile);
sk_X509_free(stack);
goto end;
}
ret=stack;
end:
BIO_free(in);
sk_X509_INFO_free(sk);
return(ret);
}
static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
{
char buf[256];
@ -230,6 +327,11 @@ static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
* the user.
*/
if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
/* Continue after extension errors too */
if (ctx->error == X509_V_ERR_INVALID_CA) ok=1;
if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1;
if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1;
if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
}
if (!v_verbose)
ERR_clear_error();

View File

@ -136,14 +136,9 @@ static int sign (X509 *x, EVP_PKEY *pkey,int days,const EVP_MD *digest,
static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
int create,int days, LHASH *conf, char *section);
static int efunc(X509_PURPOSE *pt, void *arg);
static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
static int reqfile=0;
typedef struct {
BIO *bio;
X509 *cert;
} X509_PPRINT;
int MAIN(int argc, char **argv)
{
int ret=1;
@ -609,11 +604,14 @@ bad:
}
else if (pprint == i)
{
X509_PPRINT ptmp;
ptmp.bio = STDout;
ptmp.cert = x;
X509_PURPOSE *ptmp;
int j;
BIO_printf(STDout, "Certificate purposes:\n");
X509_PURPOSE_enum(efunc, &ptmp);
for(j = 0; j < X509_PURPOSE_get_count(); j++)
{
ptmp = X509_PURPOSE_iget(j);
purpose_print(STDout, x, ptmp);
}
}
else
if (modulus == i)
@ -1227,20 +1225,18 @@ err:
return(0);
}
static int efunc(X509_PURPOSE *pt, void *arg)
static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
{
X509_PPRINT *ptmp;
int id, i, idret;
char *pname;
ptmp = arg;
id = X509_PURPOSE_get_id(pt);
pname = X509_PURPOSE_get_name(pt);
pname = X509_PURPOSE_iget_name(pt);
for(i = 0; i < 2; i++) {
idret = X509_check_purpose(ptmp->cert, id, i);
BIO_printf(ptmp->bio, "%s%s : ", pname, i ? " CA" : "");
if(idret == 1) BIO_printf(ptmp->bio, "Yes\n");
else if (idret == 0) BIO_printf(ptmp->bio, "No\n");
else BIO_printf(ptmp->bio, "Yes (WARNING code=%d)\n", idret);
idret = X509_check_purpose(cert, id, i);
BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
if(idret == 1) BIO_printf(bio, "Yes\n");
else if (idret == 0) BIO_printf(bio, "No\n");
else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
}
return 1;
}

View File

@ -66,11 +66,11 @@
*/
static BIT_STRING_BITNAME tbits[] = {
{X509_TRUST_ALL, "All Purposes", "all"},
{X509_TRUST_SSL_CLIENT, "SSL client", "sslclient"},
{X509_TRUST_SSL_SERVER, "SSL server", "sslserver"},
{X509_TRUST_EMAIL, "S/MIME email", "email"},
{X509_TRUST_OBJECT_SIGN, "Object Signing", "objsign"},
{X509_TRUST_BIT_ALL, "All Purposes", "all"},
{X509_TRUST_BIT_SSL_CLIENT, "SSL client", "sslclient"},
{X509_TRUST_BIT_SSL_SERVER, "SSL server", "sslserver"},
{X509_TRUST_BIT_EMAIL, "S/MIME email", "email"},
{X509_TRUST_BIT_OBJECT_SIGN, "Object Signing", "objsign"},
{-1, NULL, NULL}
};

View File

@ -61,12 +61,12 @@
* perl obj_dat.pl objects.h obj_dat.h
*/
#define NUM_NID 180
#define NUM_NID 181
#define NUM_SN 128
#define NUM_LN 174
#define NUM_OBJ 151
#define NUM_LN 175
#define NUM_OBJ 152
static unsigned char lvalues[1049]={
static unsigned char lvalues[1057]={
0x00, /* [ 0] OBJ_undef */
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */
@ -218,6 +218,7 @@ static unsigned char lvalues[1049]={
0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [1024] OBJ_info_access */
0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [1032] OBJ_ad_OCSP */
0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [1040] OBJ_ad_ca_issuers */
0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [1048] OBJ_OCSP_sign */
};
static ASN1_OBJECT nid_objs[NUM_NID]={
@ -471,6 +472,7 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
8,&(lvalues[1024]),0},
{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1032]),0},
{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1040]),0},
{"OCSP Signing","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1048]),0},
};
static ASN1_OBJECT *sn_objs[NUM_SN]={
@ -631,6 +633,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
&(nid_objs[73]),/* "Netscape Revocation Url" */
&(nid_objs[77]),/* "Netscape SSL Server Name" */
&(nid_objs[139]),/* "Netscape Server Gated Crypto" */
&(nid_objs[180]),/* "OCSP Signing" */
&(nid_objs[178]),/* "OCSP" */
&(nid_objs[161]),/* "PBES2" */
&(nid_objs[69]),/* "PBKDF2" */
@ -864,6 +867,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
&(nid_objs[131]),/* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */
&(nid_objs[132]),/* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */
&(nid_objs[133]),/* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */
&(nid_objs[180]),/* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */
&(nid_objs[178]),/* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */
&(nid_objs[179]),/* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */
&(nid_objs[58]),/* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */

View File

@ -935,6 +935,11 @@ extern "C" {
#define NID_ad_ca_issuers 179
#define OBJ_ad_ca_issuers OBJ_id_ad,2L
#define SN_OSCP_sign "OCSPSigning"
#define LN_OCSP_sign "OCSP Signing"
#define NID_OCSP_sign 180
#define OBJ_OCSP_sign OBJ_id_kp,9L
#include <openssl/bio.h>
#include <openssl/asn1.h>

View File

@ -572,7 +572,7 @@ DECLARE_PEM_rw(DHparams, DH)
DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
DECLARE_PEM_rw(PUBKEY, EVP_PKEY);
DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
char *, int, pem_password_cb *, void *);

View File

@ -194,4 +194,4 @@ IMPLEMENT_PEM_rw(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
IMPLEMENT_PEM_read(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey)
IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA), PrivateKey)
IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY);
IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)

View File

@ -76,8 +76,8 @@ typedef struct stack_st
#define sk_new_null() sk_new(NULL)
#define M_sk_num(sk) ((sk)->num)
#define M_sk_value(sk,n) ((sk)->data[n])
#define M_sk_num(sk) ((sk) ? (sk)->num:-1)
#define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL)
int sk_num(STACK *);
char *sk_value(STACK *, int);

View File

@ -332,21 +332,21 @@ x509_v3.o: ../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
x509_vfy.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
x509_vfy.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
x509_vfy.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
x509_vfy.o: ../../include/openssl/err.h ../../include/openssl/evp.h
x509_vfy.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
x509_vfy.o: ../../include/openssl/md2.h ../../include/openssl/md5.h
x509_vfy.o: ../../include/openssl/mdc2.h ../../include/openssl/objects.h
x509_vfy.o: ../../include/openssl/opensslconf.h
x509_vfy.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
x509_vfy.o: ../../include/openssl/des.h ../../include/openssl/dh.h
x509_vfy.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
x509_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
x509_vfy.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
x509_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
x509_vfy.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
x509_vfy.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
x509_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
x509_vfy.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
x509_vfy.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
x509_vfy.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
x509_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
x509_vfy.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
x509_vfy.o: ../cryptlib.h
x509_vfy.o: ../../include/openssl/x509v3.h ../cryptlib.h
x509name.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
x509name.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
x509name.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h

View File

@ -238,11 +238,12 @@ typedef struct x509_cinf_st
/* Bit values for trust/notrust */
#define X509_TRUST_ALL 0
#define X509_TRUST_SSL_CLIENT 1
#define X509_TRUST_SSL_SERVER 2
#define X509_TRUST_EMAIL 3
#define X509_TRUST_OBJECT_SIGN 4
#define X509_TRUST_BIT_ALL 0
#define X509_TRUST_BIT_SSL_CLIENT 1
#define X509_TRUST_BIT_SSL_SERVER 2
#define X509_TRUST_BIT_EMAIL 3
#define X509_TRUST_BIT_OBJECT_SIGN 4
typedef struct x509_cert_aux_st
{
@ -276,6 +277,24 @@ typedef struct x509_st
DECLARE_STACK_OF(X509)
DECLARE_ASN1_SET_OF(X509)
/* This is used for a table of trust checking functions */
typedef struct x509_trust_st {
int trust_id;
int trust_flags;
int (*check_trust)(struct x509_trust_st *, X509 *, int);
char *trust_name;
int trust_bit;
void *usr_data;
} X509_TRUST;
/* X509 trust ids */
#define X509_TRUST_ANY 1
#define X509_TRUST_SSL_CLIENT 2
#define X509_TRUST_SSL_SERVER 3
#define X509_TRUST_EMAIL 4
typedef struct X509_revoked_st
{
ASN1_INTEGER *serialNumber;

View File

@ -383,7 +383,10 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(LHASH *h, int type,
X509_STORE_CTX *X509_STORE_CTX_new(void)
{
return (X509_STORE_CTX *)Malloc(sizeof(X509_STORE_CTX));
X509_STORE_CTX *ctx;
ctx = (X509_STORE_CTX *)Malloc(sizeof(X509_STORE_CTX));
if(ctx) memset(ctx, 0, sizeof(X509_STORE_CTX));
return ctx;
}
void X509_STORE_CTX_free(X509_STORE_CTX *ctx)

View File

@ -61,7 +61,6 @@
#include <openssl/x509v3.h>
static int x509_purpose_get_idx(int id);
static void x509v3_cache_extensions(X509 *x);
static int ca_check(X509 *x);
@ -74,15 +73,16 @@ static int check_purpose_smime_encrypt(X509_PURPOSE *xp, X509 *x, int ca);
static int check_purpose_crl_sign(X509_PURPOSE *xp, X509 *x, int ca);
static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b);
static void xptable_free(X509_PURPOSE *p);
static X509_PURPOSE xstandard[] = {
{1, 0, check_purpose_ssl_client, "SSL client", /* NULL */},
{2, 0, check_purpose_ssl_server, "SSL server", /* NULL */},
{3, 0, check_purpose_ns_ssl_server, "Netscape SSL server", /* NULL */},
{4, 0, check_purpose_smime_sign, "S/MIME signing", /* NULL */},
{5, 0, check_purpose_smime_encrypt, "S/MIME encryption", /* NULL */},
{6, 0, check_purpose_crl_sign, "CRL signing", /* NULL */},
{-1, 0, NULL, NULL, /* NULL */}
{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL},
{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL},
{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL},
{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
{X509_PURPOSE_CRL_SIGN, X509_TRUST_ANY, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
{-1, 0, 0, NULL, NULL, NULL, NULL}
};
IMPLEMENT_STACK_OF(X509_PURPOSE)
@ -104,16 +104,35 @@ int X509_check_purpose(X509 *x, int id, int ca)
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
if(id == -1) return 1;
idx = x509_purpose_get_idx(id);
idx = X509_PURPOSE_get_by_id(id);
if(idx == -1) return -1;
pt = sk_X509_PURPOSE_value(xptable, idx);
return pt->check_purpose(pt, x,ca);
}
int X509_PURPOSE_get_count(void)
{
return sk_X509_PURPOSE_num(xptable);
}
X509_PURPOSE * X509_PURPOSE_iget(int idx)
{
return sk_X509_PURPOSE_value(xptable, idx);
}
int X509_PURPOSE_get_by_sname(char *sname)
{
int i;
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;
}
return -1;
}
static int x509_purpose_get_idx(int id)
int X509_PURPOSE_get_by_id(int id)
{
X509_PURPOSE tmp;
tmp.purpose_id = id;
@ -134,24 +153,28 @@ int X509_PURPOSE_add(X509_PURPOSE *xp)
}
}
idx = x509_purpose_get_idx(xp->purpose_id);
if(idx != -1)
idx = X509_PURPOSE_get_by_id(xp->purpose_id);
if(idx != -1) {
xptable_free(sk_X509_PURPOSE_value(xptable, idx));
sk_X509_PURPOSE_set(xptable, idx, xp);
else
if (!sk_X509_PURPOSE_push(xptable, xp))
{
} else {
if (!sk_X509_PURPOSE_push(xptable, xp)) {
X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
return 0;
}
}
}
return 1;
}
static void xptable_free(X509_PURPOSE *p)
{
if(!p) return;
if (p->purpose_flags & X509_PURPOSE_DYNAMIC)
{
if (p->purpose_flags & X509_PURPOSE_DYNAMIC_NAME)
if (p->purpose_flags & X509_PURPOSE_DYNAMIC_NAME) {
Free(p->purpose_name);
Free(p->purpose_sname);
}
Free(p);
}
}
@ -169,29 +192,26 @@ void X509_PURPOSE_add_standard(void)
X509_PURPOSE_add(xp);
}
int X509_PURPOSE_enum(int (*efunc)(X509_PURPOSE *, void *), void *usr)
{
int i;
X509_PURPOSE *xp;
if(!xptable) return 0;
for(i = 0; i < sk_X509_PURPOSE_num(xptable); i++) {
xp = sk_X509_PURPOSE_value(xptable, i);
if(!efunc(xp, usr)) return i;
}
return i;
}
int X509_PURPOSE_get_id(X509_PURPOSE *xp)
{
return xp->purpose_id;
}
char *X509_PURPOSE_get_name(X509_PURPOSE *xp)
char *X509_PURPOSE_iget_name(X509_PURPOSE *xp)
{
return xp->purpose_name;
}
char *X509_PURPOSE_iget_sname(X509_PURPOSE *xp)
{
return xp->purpose_sname;
}
int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
{
return xp->trust_id;
}
static void x509v3_cache_extensions(X509 *x)
{
BASIC_CONSTRAINTS *bs;

View File

@ -330,17 +330,23 @@ DECLARE_ASN1_SET_OF(POLICYINFO)
typedef struct x509_purpose_st {
int purpose_id;
int trust_id; /* Default trust ID */
int purpose_flags;
int (*check_purpose)(struct x509_purpose_st *, X509 *, int);
char *purpose_name;
/* void *usr_data; */ /* if we enable this it needs a free function */
char *purpose_sname;
void *usr_data;
} X509_PURPOSE;
#define X509_PURPOSE_SSL_CLIENT 1
#define X509_PURPOSE_SSL_SERVER 2
#define X509_PURPOSE_NS_SSL_SERVER 3
#define X509_PURPOSE_SMIME_SIGN 4
#define X509_PURPOSE_SMIME_ENCRYPT 5
#define X509_PURPOSE_CRL_SIGN 6
DECLARE_STACK_OF(X509_PURPOSE)
void ERR_load_X509V3_strings(void);
int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **pp);
BASIC_CONSTRAINTS *d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, unsigned char **pp, long length);
@ -522,12 +528,17 @@ int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent);
int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
int X509_check_purpose(X509 *x, int id, int ca);
int X509_PURPOSE_get_count(void);
X509_PURPOSE * X509_PURPOSE_iget(int idx);
int X509_PURPOSE_get_by_sname(char *sname);
int X509_PURPOSE_get_by_id(int id);
int X509_PURPOSE_add(X509_PURPOSE *xp);
char *X509_PURPOSE_iget_name(X509_PURPOSE *xp);
char *X509_PURPOSE_iget_sname(X509_PURPOSE *xp);
int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
void X509_PURPOSE_cleanup(void);
void X509_PURPOSE_add_standard(void);
int X509_PURPOSE_enum(int (*efunc)(X509_PURPOSE *, void *), void *usr);
int X509_PURPOSE_get_id(X509_PURPOSE *);
char * X509_PURPOSE_get_name(X509_PURPOSE *);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes

View File

@ -1914,7 +1914,7 @@ ASN1_UTCTIME_free 1938
DSA_set_default_method 1939
sk_X509_PURPOSE_set_cmp_func 1940
PEM_write_bio_DSA_PUBKEY 1941
X509_PURPOSE_get_id 1942
X509_PURPOSE_get_by_id 1942
DISPLAYTEXT_free 1943
X509V3_CRL_get_d2i 1944
ASN1_OCTET_STRING_free 1945
@ -1937,12 +1937,12 @@ ASN1_T61STRING_new 1961
ASN1_UTCTIME_new 1962
ASN1_IA5STRING_free 1963
ASN1_STRING_data 1964
X509_PURPOSE_get_name 1965
X509_PURPOSE_iget_name 1965
sk_X509_PURPOSE_delete_ptr 1966
ASN1_BIT_STRING_free 1967
X509_PURPOSE_add 1968
ASN1_UTF8STRING_free 1969
X509_PURPOSE_enum 1970
X509_PURPOSE_get 1970
sk_X509_PURPOSE_pop_free 1971
i2d_DSA_PUBKEY_fp 1972
sk_X509_PURPOSE_free 1973
@ -2076,3 +2076,13 @@ 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