Commit 74400f73 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Continued multibyte character support.

Add a bunch of functions to simplify the creation of X509_NAME structures.

Change the X509_NAME_entry_add stuff in req/ca so it no longer uses
X509_NAME_entry_count(): passing -1 has the same effect.
parent 62ac2938
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -4,6 +4,24 @@

 Changes between 0.9.4 and 0.9.5  [xx XXX 1999]

  *) Add a bunch of functions that should simplify the creation of 
     X509_NAME structures. Now you should be able to do:
     X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0);
     and have it automatically work out the correct field type and fill in
     the structures. The more adventurous can try:
     X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0);
     and it will (hopefully) work out the correct multibyte encoding.
     [Steve Henson]

  *) Change the 'req' utility to use the new field handling and multibyte
     copy routines. Before the DN field creation was handled in an ad hoc
     way in req, ca, and x509 which was rather broken and didn't support
     BMPStrings or UTF8Strings. Since some software doesn't implement
     BMPStrings or UTF8Strings yet, they can be enabled using the config file
     using the dirstring_type option. See the new comment in the default
     openssl.cnf for more info.
     [Steve Henson]

  *) Make crypto/rand/md_rand.c more robust:
     - Assure unique random numbers after fork().
     - Make sure that concurrent threads access the global counter and
+2 −4
Original line number Diff line number Diff line
@@ -1691,8 +1691,7 @@ again2:

			if (push != NULL)
				{
				if (!X509_NAME_add_entry(subject,push,
					X509_NAME_entry_count(subject),0))
				if (!X509_NAME_add_entry(subject,push, -1, 0))
					{
					if (push != NULL)
						X509_NAME_ENTRY_free(push);
@@ -2053,8 +2052,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
			strlen(buf))) == NULL)
			goto err;

		if (!X509_NAME_add_entry(n,ne,X509_NAME_entry_count(n),0))
			goto err;
		if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
		}
	if (spki == NULL)
		{
+11 −0
Original line number Diff line number Diff line
@@ -86,6 +86,17 @@ distinguished_name = req_distinguished_name
attributes		= req_attributes
x509_extensions	= v3_ca	# The extentions to add to the self signed cert

# This sets the permitted types in a DirectoryString. There are several
# options. 
# default: PrintableString, T61String, BMPString.
# pkix	 : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nobmp : PrintableString, T61String (no BMPStrings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
dirstring_type = nobmp

# req_extensions = v3_req # The extensions to add to a certificate request

[ req_distinguished_name ]
+14 −14
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@
#define ATTRIBUTES	"attributes"
#define V3_EXTENSIONS	"x509_extensions"
#define REQ_EXTENSIONS	"req_extensions"
#define DIRSTRING_TYPE	"dirstring_type"

#define DEFAULT_KEY_LENGTH	512
#define MIN_KEY_LENGTH		384
@@ -452,6 +453,13 @@ bad:
		}
	}

	p = CONF_get_string(req_conf, SECTION, DIRSTRING_TYPE);

	if(p && !ASN1_STRING_set_default_mask_asc(p)) {
		BIO_printf(bio_err, "Invalid DiretoryString setting %s", p);
		goto end;
	}

	if(!req_exts)
		req_exts = CONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
	if(req_exts) {
@@ -883,6 +891,9 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs)

	ri=req->req_info;

	/* setup version number */
	if (!ASN1_INTEGER_set(ri->version,0L)) goto err; /* version 1 */

	BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
	BIO_printf(bio_err,"into your certificate request.\n");
	BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
@@ -891,8 +902,6 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs)
	BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
	BIO_printf(bio_err,"-----\n");

	/* setup version number */
	if (!ASN1_INTEGER_set(ri->version,0L)) goto err; /* version 1 */

	if (sk_CONF_VALUE_num(sk))
		{
@@ -1003,8 +1012,7 @@ err:
static int add_DN_object(X509_NAME *n, char *text, char *def, char *value,
	     int nid, int min, int max)
	{
	int i,j,ret=0;
	X509_NAME_ENTRY *ne=NULL;
	int i,ret=0;
	MS_STATIC char buf[1024];

	BIO_printf(bio_err,"%s [%s]:",text,def);
@@ -1039,21 +1047,13 @@ static int add_DN_object(X509_NAME *n, char *text, char *def, char *value,
		}
	buf[--i]='\0';

	j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
	if (req_fix_data(nid,&j,i,min,max) == 0)
		goto err;
#ifdef CHARSET_EBCDIC
	ebcdic2ascii(buf, buf, i);
#endif
	if ((ne=X509_NAME_ENTRY_create_by_NID(NULL,nid,j,(unsigned char *)buf,
		strlen(buf)))
		== NULL) goto err;
	if (!X509_NAME_add_entry(n,ne,X509_NAME_entry_count(n),0))
		goto err;

	if (!X509_NAME_add_entry_by_NID(n,nid, MBSTRING_ASC,
				(unsigned char *) buf, -1,-1,0)) goto err;
	ret=1;
err:
	if (ne != NULL) X509_NAME_ENTRY_free(ne);
	return(ret);
	}

+29 −0
Original line number Diff line number Diff line
@@ -91,6 +91,35 @@ unsigned long ASN1_STRING_get_default_mask(void)
	return dirstring_mask;
}

/* This function sets the default to various "flavours" of configuration.
 * based on an ASCII string. Currently this is:
 * MASK:XXXX : a numerical mask value.
 * nobmp : Don't use BMPStrings (just Printable, T61).
 * pkix : PKIX recommendation in RFC2459.
 * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
 * default:   the default value, Printable, T61, BMP.
 */

int ASN1_STRING_set_default_mask_asc(char *p)
{
	unsigned long mask;
	char *end;
	if(!strncmp(p, "MASK:", 5)) {
		if(!p[5]) return 0;
		mask = strtoul(p + 5, &end, 0);
		if(*end) return 0;
	} else if(!strcmp(p, "nobmp"))
			 mask = B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING;
	else if(!strcmp(p, "pkix"))
			mask = B_ASN1_PRINTABLESTRING | B_ASN1_BMPSTRING;
	else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
	else if(!strcmp(p, "default"))
	    mask = B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_BMPSTRING;
	else return 0;
	ASN1_STRING_set_default_mask(mask);
	return 1;
}

/* These functions take a string in UTF8, ASCII or multibyte form and
 * a mask of permissible ASN1 string types. It then works out the minimal
 * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
Loading