提交 74400f73 编写于 作者: D Dr. Stephen Henson

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.
上级 62ac2938
......@@ -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
......
......@@ -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)
{
......
......@@ -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 ]
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -85,7 +85,7 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
tbl->minsize, tbl->maxsize);
else ret = ASN1_mbstring_copy(out, in, inlen, inform, 0);
if(ret <= 0) return NULL;
return str;
return *out;
}
/* Now the tables and helper functions for the string table:
......
......@@ -744,6 +744,7 @@ void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)());
ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
void ASN1_STRING_set_default_mask(unsigned long mask);
int ASN1_STRING_set_default_mask_asc(char *p);
unsigned long ASN1_STRING_get_default_mask(void);
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask);
......
......@@ -859,8 +859,16 @@ X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
int loc, int set);
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
unsigned char *bytes, int len, int loc, int set);
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
unsigned char *bytes, int len, int loc, int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
char *field, int type, unsigned char *bytes, int len);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
int type,unsigned char *bytes, int len);
int X509_NAME_add_entry_by_txt(X509_NAME *name, char *field, int type,
unsigned char *bytes, int len, int loc, int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
ASN1_OBJECT *obj, int type,unsigned char *bytes,
int len);
......@@ -979,6 +987,7 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
#define X509_F_X509_LOAD_CRL_FILE 112
#define X509_F_X509_NAME_ADD_ENTRY 113
#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114
#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131
#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115
#define X509_F_X509_NAME_ONELINE 116
#define X509_F_X509_NAME_PRINT 117
......@@ -1000,6 +1009,7 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
#define X509_R_ERR_ASN1_LIB 102
#define X509_R_INVALID_DIRECTORY 113
#define X509_R_INVALID_FIELD_NAME 119
#define X509_R_KEY_TYPE_MISMATCH 115
#define X509_R_KEY_VALUES_MISMATCH 116
#define X509_R_LOADING_CERT_DIR 103
......
......@@ -80,6 +80,7 @@ static ERR_STRING_DATA X509_str_functs[]=
{ERR_PACK(0,X509_F_X509_LOAD_CRL_FILE,0), "X509_load_crl_file"},
{ERR_PACK(0,X509_F_X509_NAME_ADD_ENTRY,0), "X509_NAME_add_entry"},
{ERR_PACK(0,X509_F_X509_NAME_ENTRY_CREATE_BY_NID,0), "X509_NAME_ENTRY_create_by_NID"},
{ERR_PACK(0,X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,0), "X509_NAME_ENTRY_create_by_txt"},
{ERR_PACK(0,X509_F_X509_NAME_ENTRY_SET_OBJECT,0), "X509_NAME_ENTRY_set_object"},
{ERR_PACK(0,X509_F_X509_NAME_ONELINE,0), "X509_NAME_oneline"},
{ERR_PACK(0,X509_F_X509_NAME_PRINT,0), "X509_NAME_print"},
......@@ -104,6 +105,7 @@ static ERR_STRING_DATA X509_str_reasons[]=
{X509_R_CERT_ALREADY_IN_HASH_TABLE ,"cert already in hash table"},
{X509_R_ERR_ASN1_LIB ,"err asn1 lib"},
{X509_R_INVALID_DIRECTORY ,"invalid directory"},
{X509_R_INVALID_FIELD_NAME ,"invalid field name"},
{X509_R_KEY_TYPE_MISMATCH ,"key type mismatch"},
{X509_R_KEY_VALUES_MISMATCH ,"key values mismatch"},
{X509_R_LOADING_CERT_DIR ,"loading cert dir"},
......
......@@ -171,6 +171,33 @@ X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
return(ret);
}
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
unsigned char *bytes, int len, int loc, int set)
{
X509_NAME_ENTRY *ne;
ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
if(!ne) return 0;
return X509_NAME_add_entry(name, ne, loc, set);
}
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
unsigned char *bytes, int len, int loc, int set)
{
X509_NAME_ENTRY *ne;
ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
if(!ne) return 0;
return X509_NAME_add_entry(name, ne, loc, set);
}
int X509_NAME_add_entry_by_txt(X509_NAME *name, char *field, int type,
unsigned char *bytes, int len, int loc, int set)
{
X509_NAME_ENTRY *ne;
ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
if(!ne) return 0;
return X509_NAME_add_entry(name, ne, loc, set);
}
/* if set is -1, append to previous set, 0 'a new one', and 1,
* prepend to the guy we are about to stomp on. */
int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
......@@ -236,6 +263,21 @@ err:
return(0);
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
char *field, int type, unsigned char *bytes, int len)
{
ASN1_OBJECT *obj;
obj=OBJ_txt2obj(field, 0);
if (obj == NULL)
{
X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
X509_R_INVALID_FIELD_NAME);
return(NULL);
}
return(X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len));
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
int type, unsigned char *bytes, int len)
{
......
......@@ -1993,3 +1993,8 @@ EVP_PKEY_get_RSA 2017
EVP_PKEY_get_DH 2018
EVP_PKEY_get_DSA 2019
X509_PURPOSE_cleanup 2020
ASN1_STRING_set_default_mask_asc 2021
X509_NAME_add_entry_by_txt 2022
X509_NAME_add_entry_by_NID 2023
X509_NAME_add_entry_by_OBJ 2024
X509_NAME_ENTRY_create_by_txt 2025
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册