Commit 6447cce3 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Simplify the trust structure: basically zap the bit strings and

represent everything by OIDs.
parent 76997b7d
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -4,6 +4,19 @@

 Changes between 0.9.4 and 0.9.5  [xx XXX 1999]

  *) Simplify the trust setting structure and code. Now we just have
     two sequences of OIDs for trusted and rejected settings. These will
     typically have values the same as the extended key usage extension
     and any application specific purposes.

     The trust checking code now has a default behaviour: it will just
     check for an object with the same NID as the passed id. Functions can
     be provided to override either the default behaviour or the behaviour
     for a given id. SSL client, server and email already have functions
     in place for compatability: they check the NID and also return "trusted"
     if the certificate is self signed.
     [Steve Henson]

  *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the
     traditional format into an EVP_PKEY structure.
     [Steve Henson]
+21 −28
Original line number Diff line number Diff line
@@ -146,15 +146,16 @@ int MAIN(int argc, char **argv)
	int ret=1;
	X509_REQ *req=NULL;
	X509 *x=NULL,*xca=NULL;
	ASN1_OBJECT *objtmp;
	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
	int i,num,badops=0;
	BIO *out=NULL;
	BIO *STDout=NULL;
	STACK *trust = NULL, *reject = NULL;
	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
	int informat,outformat,keyformat,CAformat,CAkeyformat;
	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
	char *CAkeyfile=NULL,*CAserial=NULL;
	char *alias=NULL, *trstr=NULL;
	char *alias=NULL;
	int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0;
	int trustout=0,clrtrust=0,clrreject=0,aliasout=0;
@@ -297,27 +298,25 @@ int MAIN(int argc, char **argv)
		else if (strcmp(*argv,"-addtrust") == 0)
			{
			if (--argc < 1) goto bad;
			trstr= *(++argv);
			if(!X509_trust_set_bit_asc(NULL, trstr, 0)) {
			if(!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
				BIO_printf(bio_err,
					"Unknown trust value %s\n", trstr);
					"Invalid trust object value %s\n", *argv);
				goto bad;
			}
			if(!trust) trust = sk_new_null();
			sk_push(trust, trstr);
			if(!trust) trust = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(trust, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-addreject") == 0)
			{
			if (--argc < 1) goto bad;
			trstr= *(++argv);
			if(!X509_reject_set_bit_asc(NULL, trstr, 0)) {
			if(!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
				BIO_printf(bio_err,
					"Unknown trust value %s\n", trstr);
					"Invalid reject object value %s\n", *argv);
				goto bad;
			}
			if(!reject) reject = sk_new_null();
			sk_push(reject, trstr);
			if(!reject) reject = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(reject, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-setalias") == 0)
@@ -521,15 +520,9 @@ bad:
		X509_gmtime_adj(X509_get_notBefore(x),0);
	        X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);

#if 0
		X509_PUBKEY_free(ci->key);
		ci->key=req->req_info->pubkey;
	        req->req_info->pubkey=NULL;
#else
		pkey = X509_REQ_get_pubkey(req);
		X509_set_pubkey(x,pkey);
		EVP_PKEY_free(pkey);
#endif
		}
	else
		x=load_cert(infile,informat);
@@ -566,23 +559,21 @@ bad:

	if(alias) X509_alias_set(x, (unsigned char *)alias, -1);

	if(clrtrust) X509_trust_set_bit(x, -1, 0);
	if(clrreject) X509_reject_set_bit(x, -1, 0);
	if(clrtrust) X509_trust_clear(x);
	if(clrreject) X509_reject_clear(x);

	if(trust) {
		for(i = 0; i < sk_num(trust); i++) {
			trstr = sk_value(trust, i);
			X509_trust_set_bit_asc(x, trstr, 1);
		for(i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
			objtmp = sk_ASN1_OBJECT_value(trust, i);
			X509_radd_trust_object(x, objtmp);
		}
		sk_free(trust);
	}

	if(reject) {
		for(i = 0; i < sk_num(reject); i++) {
			trstr = sk_value(reject, i);
			X509_reject_set_bit_asc(x, trstr, 1);
		for(i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
			objtmp = sk_ASN1_OBJECT_value(reject, i);
			X509_radd_reject_object(x, objtmp);
		}
		sk_free(reject);
	}

	if (num)
@@ -887,6 +878,8 @@ end:
	EVP_PKEY_free(Upkey);
	EVP_PKEY_free(CApkey);
	X509_REQ_free(rq);
	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
	EXIT(ret);
	}

+9 −45
Original line number Diff line number Diff line
@@ -65,73 +65,37 @@
/* X509_CERT_AUX and string set routines
 */

static BIT_STRING_BITNAME tbits[] = {
{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}
};

int X509_trust_set_bit_asc(X509 *x, char *str, int value)
{
	int bitnum;
	bitnum = ASN1_BIT_STRING_num_asc(str, tbits);
	if(bitnum < 0) return 0;
	if(x) return X509_trust_set_bit(x, bitnum, value);
	return 1;
}

int X509_reject_set_bit_asc(X509 *x, char *str, int value)
{
	int bitnum;
	bitnum = ASN1_BIT_STRING_num_asc(str, tbits);
	if(bitnum < 0) return 0;
	if(x) return X509_reject_set_bit(x, bitnum, value);
	return 1;
}


int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
{
	char oidstr[80], first;
	int i;
	if(!aux) return 1;
	if(aux->trust) {
		BIO_printf(out, "%*sTrusted Uses:\n", indent, "");
		ASN1_BIT_STRING_name_print(out, aux->trust, tbits, indent + 2);
	} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
	if(aux->reject) {
		BIO_printf(out, "%*sRejected Uses:\n", indent, "");
		ASN1_BIT_STRING_name_print(out, aux->reject, tbits, indent + 2);
	} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
	if(aux->othertrust) {
		first = 1;
		BIO_printf(out, "%*sOther Trusted Uses:\n%*s",
		BIO_printf(out, "%*sTrusted Uses:\n%*s",
						indent, "", indent + 2, "");
		for(i = 0; i < sk_ASN1_OBJECT_num(aux->othertrust); i++) {
		for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
			if(!first) BIO_puts(out, ", ");
			else first = 0;
			OBJ_obj2txt(oidstr, 80,
				sk_ASN1_OBJECT_value(aux->othertrust, i), 0);
				sk_ASN1_OBJECT_value(aux->trust, i), 0);
			BIO_puts(out, oidstr);
		}
		BIO_puts(out, "\n");
	}
	if(aux->otherreject) {
	} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
	if(aux->reject) {
		first = 1;
		BIO_printf(out, "%*sOther Rejected Uses:\n%*s",
		BIO_printf(out, "%*sRejected Uses:\n%*s",
						indent, "", indent + 2, "");
		for(i = 0; i < sk_ASN1_OBJECT_num(aux->otherreject); i++) {
		for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
			if(!first) BIO_puts(out, ", ");
			else first = 0;
			OBJ_obj2txt(oidstr, 80,
				sk_ASN1_OBJECT_value(aux->otherreject, i), 0);
				sk_ASN1_OBJECT_value(aux->reject, i), 0);
			BIO_puts(out, oidstr);
		}
		BIO_puts(out, "\n");
	}
	} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
	if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
							aux->alias->data);
	return 1;
+36 −56
Original line number Diff line number Diff line
@@ -78,16 +78,12 @@ X509_CERT_AUX *d2i_X509_CERT_AUX(X509_CERT_AUX **a, unsigned char **pp, long len
	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();

	M_ASN1_D2I_get_opt(ret->trust, d2i_ASN1_BIT_STRING,
							V_ASN1_BIT_STRING);
	M_ASN1_D2I_get_IMP_opt(ret->reject, d2i_ASN1_BIT_STRING,0,
							V_ASN1_BIT_STRING);

	M_ASN1_D2I_get_seq_opt_type(ASN1_OBJECT, ret->othertrust,
	M_ASN1_D2I_get_seq_opt_type(ASN1_OBJECT, ret->trust,
					d2i_ASN1_OBJECT, ASN1_OBJECT_free);
	M_ASN1_D2I_get_IMP_set_opt_type(ASN1_OBJECT, ret->otherreject,
					d2i_ASN1_OBJECT, ASN1_OBJECT_free, 1);
	M_ASN1_D2I_get_IMP_set_opt_type(ASN1_OBJECT, ret->reject,
					d2i_ASN1_OBJECT, ASN1_OBJECT_free, 0);
	M_ASN1_D2I_get_opt(ret->alias, d2i_ASN1_UTF8STRING, V_ASN1_UTF8STRING);
	M_ASN1_D2I_get_opt(ret->keyid, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING);
	M_ASN1_D2I_get_opt(ret->other, d2i_ASN1_TYPE, V_ASN1_SEQUENCE);

	M_ASN1_D2I_Finish(a, X509_CERT_AUX_free, ASN1_F_D2I_X509_CERT_AUX);
@@ -100,9 +96,8 @@ X509_CERT_AUX *X509_CERT_AUX_new()
	M_ASN1_New_Malloc(ret, X509_CERT_AUX);
	ret->trust = NULL;
	ret->reject = NULL;
	ret->othertrust = NULL;
	ret->otherreject = NULL;
	ret->alias = NULL;
	ret->keyid = NULL;
	ret->other = NULL;
	return(ret);
	M_ASN1_New_Error(ASN1_F_X509_CERT_AUX_NEW);
@@ -111,11 +106,10 @@ X509_CERT_AUX *X509_CERT_AUX_new()
void X509_CERT_AUX_free(X509_CERT_AUX *a)
{
	if(a == NULL) return;
	ASN1_BIT_STRING_free(a->trust);
	ASN1_BIT_STRING_free(a->reject);
	sk_ASN1_OBJECT_pop_free(a->othertrust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(a->otherreject, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(a->trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(a->reject, ASN1_OBJECT_free);
	ASN1_UTF8STRING_free(a->alias);
	ASN1_OCTET_STRING_free(a->keyid);
	ASN1_TYPE_free(a->other);
	Free((char *)a);
}
@@ -124,24 +118,20 @@ int i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **pp)
{
	M_ASN1_I2D_vars(a);

	M_ASN1_I2D_len(a->trust, i2d_ASN1_BIT_STRING);	
	M_ASN1_I2D_len_IMP_opt(a->reject, i2d_ASN1_BIT_STRING);

	M_ASN1_I2D_len_SEQUENCE_opt_type(ASN1_OBJECT, a->othertrust, i2d_ASN1_OBJECT);
	M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->otherreject, i2d_ASN1_OBJECT, 1);
	M_ASN1_I2D_len_SEQUENCE_opt_type(ASN1_OBJECT, a->trust, i2d_ASN1_OBJECT);
	M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->reject, i2d_ASN1_OBJECT, 0);

	M_ASN1_I2D_len(a->alias, i2d_ASN1_UTF8STRING);
	M_ASN1_I2D_len(a->keyid, i2d_ASN1_OCTET_STRING);
	M_ASN1_I2D_len(a->other, i2d_ASN1_TYPE);

	M_ASN1_I2D_seq_total();

	M_ASN1_I2D_put(a->trust, i2d_ASN1_BIT_STRING);	
	M_ASN1_I2D_put_IMP_opt(a->reject, i2d_ASN1_BIT_STRING, 0);

	M_ASN1_I2D_put_SEQUENCE_opt_type(ASN1_OBJECT, a->othertrust, i2d_ASN1_OBJECT);
	M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->otherreject, i2d_ASN1_OBJECT, 1);
	M_ASN1_I2D_put_SEQUENCE_opt_type(ASN1_OBJECT, a->trust, i2d_ASN1_OBJECT);
	M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->reject, i2d_ASN1_OBJECT, 0);

	M_ASN1_I2D_put(a->alias, i2d_ASN1_UTF8STRING);
	M_ASN1_I2D_put(a->keyid, i2d_ASN1_OCTET_STRING);
	M_ASN1_I2D_put(a->other, i2d_ASN1_TYPE);

	M_ASN1_I2D_finish();
@@ -169,51 +159,41 @@ unsigned char *X509_alias_get(X509 *x, int *len)
	return x->aux->alias->data;
}

int X509_trust_set_bit(X509 *x, int bit, int value)
int X509_radd_trust_object(X509 *x, ASN1_OBJECT *obj)
{
	X509_CERT_AUX *aux;
	if(bit == -1) {
		if(x->aux && x->aux->trust) {
			ASN1_BIT_STRING_free(x->aux->trust);
			x->aux->trust = NULL;
		}
		return 1;
	}
	ASN1_OBJECT *objtmp;
	if(!(objtmp = OBJ_dup(obj))) return 0;
	if(!(aux = aux_get(x))) return 0;
	if(!aux->trust && !(aux->trust = ASN1_BIT_STRING_new())) return 0;
	return ASN1_BIT_STRING_set_bit(aux->trust, bit, value);
	if(!aux->trust
		&& !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0;
	return sk_ASN1_OBJECT_push(aux->trust, objtmp);
}

int X509_reject_set_bit(X509 *x, int bit, int value)
int X509_radd_reject_object(X509 *x, ASN1_OBJECT *obj)
{
	X509_CERT_AUX *aux;
	if(bit == -1) {
		if(x->aux && x->aux->reject) {
			ASN1_BIT_STRING_free(x->aux->reject);
			x->aux->reject = NULL;
		}
		return 1;
	}
	ASN1_OBJECT *objtmp;
	if(!(objtmp = OBJ_dup(obj))) return 0;
	if(!(aux = aux_get(x))) return 0;
	if(!aux->reject && !(aux->reject = ASN1_BIT_STRING_new())) return 0;
	return ASN1_BIT_STRING_set_bit(aux->reject, bit, value);
	if(!aux->reject
		&& !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0;
	return sk_ASN1_OBJECT_push(aux->reject, objtmp);
}

int X509_add_trust_object(X509 *x, ASN1_OBJECT *obj)
void X509_trust_clear(X509 *x)
{
	X509_CERT_AUX *aux;
	if(!(aux = aux_get(x))) return 0;
	if(!aux->othertrust
		&& !(aux->othertrust = sk_ASN1_OBJECT_new_null())) return 0;
	return sk_ASN1_OBJECT_push(aux->othertrust, obj);
	if(x->aux && x->aux->trust) {
		sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
		x->aux->trust = NULL;
	}
}

int X509_add_reject_object(X509 *x, ASN1_OBJECT *obj)
void X509_reject_clear(X509 *x)
{
	X509_CERT_AUX *aux;
	if(!(aux = aux_get(x))) return 0;
	if(!aux->otherreject
		&& !(aux->otherreject = sk_ASN1_OBJECT_new_null())) return 0;
	return sk_ASN1_OBJECT_push(aux->otherreject, obj);
	if(x->aux && x->aux->reject) {
		sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
		x->aux->reject = NULL;
	}
}
+8 −20
Original line number Diff line number Diff line
@@ -236,22 +236,12 @@ typedef struct x509_cinf_st
 * the end of the certificate itself
 */

/* Bit values for trust/reject */

#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
	{
	ASN1_BIT_STRING *trust;			/* trusted uses */
	ASN1_BIT_STRING *reject;		/* rejected uses */
	STACK_OF(ASN1_OBJECT) *othertrust;	/* extra uses */
	STACK_OF(ASN1_OBJECT) *otherreject;	/* extra rejected uses */
	STACK_OF(ASN1_OBJECT) *trust;		/* trusted uses */
	STACK_OF(ASN1_OBJECT) *reject;		/* rejected uses */
	ASN1_UTF8STRING *alias;			/* "friendly name" */
	ASN1_OCTET_STRING *keyid;		/* key id of private key */
	ASN1_TYPE *other;			/* other unspecified info */
	} X509_CERT_AUX;

@@ -830,13 +820,11 @@ X509_CERT_AUX * d2i_X509_CERT_AUX(X509_CERT_AUX **a,unsigned char **pp,
								long length);
int X509_alias_set(X509 *x, unsigned char *name, int len);
unsigned char * X509_alias_get(X509 *x, int *len);
int X509_trust_set_bit(X509 *x, int bit, int value);
int X509_reject_set_bit(X509 *x, int bit, int value);
int X509_add_trust_object(X509 *x, ASN1_OBJECT *obj);
int X509_add_reject_object(X509 *x, ASN1_OBJECT *obj);

int X509_trust_set_bit_asc(X509 *x, char *str, int value);
int X509_reject_set_bit_asc(X509 *x, char *str, int value);
int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
int X509_radd_trust_object(X509 *x, ASN1_OBJECT *obj);
int X509_radd_reject_object(X509 *x, ASN1_OBJECT *obj);
void X509_trust_clear(X509 *x);
void X509_reject_clear(X509 *x);

X509_REVOKED *	X509_REVOKED_new(void);
void		X509_REVOKED_free(X509_REVOKED *a);
Loading