Loading CHANGES +25 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,31 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] Changes between 0.9.4 and 0.9.5 [xx XXX 1999] *) Initial changes to the 'req' utility to allow request generation automation. This will allow an application to just generate a template file containing all the field values and have req construct the request. Initial support for X509_ATTRIBUTE handling. Stacks of these are used all over the place including certificate requests and PKCS#7 structures. They are currently handled manually where necessary with some primitive wrappers for PKCS#7. The new functions behave in a manner analagous to the X509 extension functions: they allow attributes to be looked up by NID and added. Later something similar to the X509V3 code would be desirable to automatically handle the encoding, decoding and printing of the more complex types. The string types like challengePassword can be handled by the string table fuctions. Also modified the multi byte string table handling. Now there is a 'global mask' which masks out certain types. The table itself can use the flag STABLE_NO_MASK to ignore the mask setting: this is useful when for example there is only one permissible type (as in countryName) and using the mask might result in no valid types at all. [Steve Henson] *) Clean up 'Finished' handling, and add functions SSL_get_finished and *) Clean up 'Finished' handling, and add functions SSL_get_finished and SSL_get_peer_finished to allow applications to obtain the latest SSL_get_peer_finished to allow applications to obtain the latest Finished messages sent to the peer or expected from the peer, Finished messages sent to the peer or expected from the peer, Loading apps/openssl.cnf +3 −4 Original line number Original line Diff line number Diff line Loading @@ -95,16 +95,15 @@ x509_extensions = v3_ca # The extentions to add to the self signed cert # input_password = secret # input_password = secret # output_password = secret # output_password = secret # This sets the permitted types in a DirectoryString. There are several # This sets a mask for permitted string types. There are several options. # options. # default: PrintableString, T61String, BMPString. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString. # pkix : PrintableString, BMPString. # utf8only: only UTF8Strings. # utf8only: only UTF8Strings. # nobmp : PrintableString, T61String (no BMPStrings). # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # MASK:XXXX a literal mask value. # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings # so use this option with caution! # so use this option with caution! dirstring_type = nobmp string_mask = nombstr # req_extensions = v3_req # The extensions to add to a certificate request # req_extensions = v3_req # The extensions to add to a certificate request Loading apps/req.c +247 −26 Original line number Original line Diff line number Diff line Loading @@ -78,11 +78,12 @@ #define BITS "default_bits" #define BITS "default_bits" #define KEYFILE "default_keyfile" #define KEYFILE "default_keyfile" #define PROMPT "prompt" #define DISTINGUISHED_NAME "distinguished_name" #define DISTINGUISHED_NAME "distinguished_name" #define ATTRIBUTES "attributes" #define ATTRIBUTES "attributes" #define V3_EXTENSIONS "x509_extensions" #define V3_EXTENSIONS "x509_extensions" #define REQ_EXTENSIONS "req_extensions" #define REQ_EXTENSIONS "req_extensions" #define DIRSTRING_TYPE "dirstring_type" #define STRING_MASK "string_mask" #define DEFAULT_KEY_LENGTH 512 #define DEFAULT_KEY_LENGTH 512 #define MIN_KEY_LENGTH 384 #define MIN_KEY_LENGTH 384 Loading @@ -109,6 +110,11 @@ */ */ static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs); static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, STACK_OF(CONF_VALUE) *attr, int attribs); static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text, static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text, char *def, char *value, int nid, int min, char *def, char *value, int nid, int min, int max); int max); Loading Loading @@ -491,10 +497,10 @@ bad: if(!passout) if(!passout) passout = CONF_get_string(req_conf, SECTION, "output_password"); passout = CONF_get_string(req_conf, SECTION, "output_password"); p = CONF_get_string(req_conf, SECTION, DIRSTRING_TYPE); p = CONF_get_string(req_conf, SECTION, STRING_MASK); if(p && !ASN1_STRING_set_default_mask_asc(p)) { if(p && !ASN1_STRING_set_default_mask_asc(p)) { BIO_printf(bio_err, "Invalid DiretoryString setting %s", p); BIO_printf(bio_err, "Invalid global string mask setting %s", p); goto end; goto end; } } Loading Loading @@ -892,46 +898,47 @@ end: static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) { { int ret=0,i; int ret=0,i; char *p,*q; char no_prompt = 0; X509_REQ_INFO *ri; STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; char buf[100]; char *tmp, *dn_sect,*attr_sect; int nid,min,max; char *type,*def,*tmp,*value,*tmp_attr; tmp=CONF_get_string(req_conf,SECTION,PROMPT); STACK_OF(CONF_VALUE) *sk, *attr=NULL; if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1; CONF_VALUE *v; tmp=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); dn_sect=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); if (tmp == NULL) if (dn_sect == NULL) { { BIO_printf(bio_err,"unable to find '%s' in config\n", BIO_printf(bio_err,"unable to find '%s' in config\n", DISTINGUISHED_NAME); DISTINGUISHED_NAME); goto err; goto err; } } sk=CONF_get_section(req_conf,tmp); dn_sk=CONF_get_section(req_conf,dn_sect); if (sk == NULL) if (dn_sk == NULL) { { BIO_printf(bio_err,"unable to get '%s' section\n",tmp); BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect); goto err; goto err; } } tmp_attr=CONF_get_string(req_conf,SECTION,ATTRIBUTES); attr_sect=CONF_get_string(req_conf,SECTION,ATTRIBUTES); if (tmp_attr == NULL) if (attr_sect == NULL) attr=NULL; attr_sk=NULL; else else { { attr=CONF_get_section(req_conf,tmp_attr); attr_sk=CONF_get_section(req_conf,attr_sect); if (attr == NULL) if (attr_sk == NULL) { { BIO_printf(bio_err,"unable to get '%s' section\n",tmp_attr); BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect); goto err; goto err; } } } } ri=req->req_info; /* setup version number */ /* setup version number */ if (!ASN1_INTEGER_set(ri->version,0L)) goto err; /* version 1 */ if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */ if(no_prompt) i = auto_info(req, dn_sk, attr_sk, attribs); else i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs); if(!i) goto err; #if 0 BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); 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,"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"); BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); Loading Loading @@ -1039,7 +1046,7 @@ start2: for (;;) BIO_printf(bio_err,"No template, please set one up.\n"); BIO_printf(bio_err,"No template, please set one up.\n"); goto err; goto err; } } #endif X509_REQ_set_pubkey(req,pkey); X509_REQ_set_pubkey(req,pkey); ret=1; ret=1; Loading @@ -1047,6 +1054,220 @@ err: return(ret); return(ret); } } static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs) { int i; char *p,*q; char buf[100]; int nid,min,max; char *type,*def,*value; CONF_VALUE *v; X509_NAME *subj; subj = X509_REQ_get_subject_name(req); 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"); BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n"); BIO_printf(bio_err,"For some fields there will be a default value,\n"); BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); BIO_printf(bio_err,"-----\n"); if (sk_CONF_VALUE_num(dn_sk)) { i= -1; start: for (;;) { i++; if (sk_CONF_VALUE_num(dn_sk) <= i) break; v=sk_CONF_VALUE_value(dn_sk,i); p=q=NULL; type=v->name; if(!check_end(type,"_min") || !check_end(type,"_max") || !check_end(type,"_default") || !check_end(type,"_value")) continue; /* Skip past any leading X. X: X, etc to allow for * multiple instances */ for(p = v->name; *p ; p++) if ((*p == ':') || (*p == ',') || (*p == '.')) { p++; if(*p) type = p; break; } /* If OBJ not recognised ignore it */ if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start; sprintf(buf,"%s_default",v->name); if ((def=CONF_get_string(req_conf,dn_sect,buf)) == NULL) def=""; sprintf(buf,"%s_value",v->name); if ((value=CONF_get_string(req_conf,dn_sect,buf)) == NULL) value=NULL; sprintf(buf,"%s_min",v->name); min=(int)CONF_get_number(req_conf,dn_sect,buf); sprintf(buf,"%s_max",v->name); max=(int)CONF_get_number(req_conf,dn_sect,buf); if (!add_DN_object(subj,v->value,def,value,nid, min,max)) return 0; } if (X509_NAME_entry_count(subj) == 0) { BIO_printf(bio_err,"error, no objects specified in config file\n"); return 0; } if (attribs) { if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)) { BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); BIO_printf(bio_err,"to be sent with your certificate request\n"); } i= -1; start2: for (;;) { i++; if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) break; v=sk_CONF_VALUE_value(attr_sk,i); type=v->name; if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start2; sprintf(buf,"%s_default",type); if ((def=CONF_get_string(req_conf,attr_sect,buf)) == NULL) def=""; sprintf(buf,"%s_value",type); if ((value=CONF_get_string(req_conf,attr_sect,buf)) == NULL) value=NULL; sprintf(buf,"%s_min",type); min=(int)CONF_get_number(req_conf,attr_sect,buf); sprintf(buf,"%s_max",type); max=(int)CONF_get_number(req_conf,attr_sect,buf); if (!add_attribute_object(req->req_info->attributes, v->value,def,value,nid,min,max)) return 0; } } } else { BIO_printf(bio_err,"No template, please set one up.\n"); return 0; } return 1; } static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, STACK_OF(CONF_VALUE) *attr_sk, int attribs) { int i; char *p,*q; char *type; CONF_VALUE *v; X509_NAME *subj; subj = X509_REQ_get_subject_name(req); for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { v=sk_CONF_VALUE_value(dn_sk,i); p=q=NULL; type=v->name; /* Skip past any leading X. X: X, etc to allow for * multiple instances */ for(p = v->name; *p ; p++) if ((*p == ':') || (*p == ',') || (*p == '.')) { p++; if(*p) type = p; break; } if (!X509_NAME_add_entry_by_txt(subj,type, MBSTRING_ASC, (unsigned char *) v->value,-1,-1,0)) return 0; } if (!X509_NAME_entry_count(subj)) { BIO_printf(bio_err,"error, no objects specified in config file\n"); return 0; } #if 0 if (attribs) { if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)) { BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); BIO_printf(bio_err,"to be sent with your certificate request\n"); } i= -1; start2: for (;;) { i++; if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) break; v=sk_CONF_VALUE_value(attr_sk,i); type=v->name; if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start2; sprintf(buf,"%s_default",type); if ((def=CONF_get_string(req_conf,attr_sect,buf)) == NULL) def=""; sprintf(buf,"%s_value",type); if ((value=CONF_get_string(req_conf,attr_sect,buf)) == NULL) value=NULL; sprintf(buf,"%s_min",type); min=(int)CONF_get_number(req_conf,attr_sect,buf); sprintf(buf,"%s_max",type); max=(int)CONF_get_number(req_conf,attr_sect,buf); if (!add_attribute_object(ri->attributes, v->value,def,value,nid,min,max)) return 0; } } } else { BIO_printf(bio_err,"No template, please set one up.\n"); return 0; } #endif return 1; } static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, int nid, int min, int max) int nid, int min, int max) { { Loading crypto/asn1/a_mbstr.c +1 −49 Original line number Original line Diff line number Diff line Loading @@ -72,54 +72,6 @@ static int cpy_univ(unsigned long value, void *arg); static int cpy_utf8(unsigned long value, void *arg); static int cpy_utf8(unsigned long value, void *arg); static int is_printable(unsigned long value); static int is_printable(unsigned long value); /* This is the default mask for the mbstring functions: it is designed * to be a "safe" DirectoryString. Netscape messenger crashes when it * receives a certificate containing a BMPString so by default we don't * use them unless we have to. */ static long dirstring_mask = B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_BMPSTRING; void ASN1_STRING_set_default_mask(unsigned long mask) { dirstring_mask = mask; } 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 /* 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 * a mask of permissible ASN1 string types. It then works out the minimal * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) Loading Loading @@ -147,7 +99,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, char strbuf[32]; char strbuf[32]; int (*cpyfunc)(unsigned long,void *) = NULL; int (*cpyfunc)(unsigned long,void *) = NULL; if(len == -1) len = strlen((const char *)in); if(len == -1) len = strlen((const char *)in); if(!mask) mask = dirstring_mask; if(!mask) mask = DIRSTRING_TYPE; /* First do a string check and work out the number of characters */ /* First do a string check and work out the number of characters */ switch(inform) { switch(inform) { Loading crypto/asn1/a_strnid.c +65 −14 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,53 @@ static void st_free(ASN1_STRING_TABLE *tbl); static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b); static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b); static int table_cmp(ASN1_STRING_TABLE *a, ASN1_STRING_TABLE *b); static int table_cmp(ASN1_STRING_TABLE *a, ASN1_STRING_TABLE *b); /* This is the global mask for the mbstring functions: this is use to * mask out certain types (such as BMPString and UTF8String) because * certain software (e.g. Netscape) has problems with them. */ static long global_mask = 0xFFFFFFFFL; void ASN1_STRING_set_default_mask(unsigned long mask) { global_mask = mask; } unsigned long ASN1_STRING_get_default_mask(void) { return global_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, "nombchar")) mask = ~(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING); else if(!strcmp(p, "pkix")) mask = ~B_ASN1_T61STRING; else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING; else if(!strcmp(p, "default")) mask = 0xFFFFFFFFL; else return 0; ASN1_STRING_set_default_mask(mask); return 1; } /* The following function generates an ASN1_STRING based on limits in a table. /* The following function generates an ASN1_STRING based on limits in a table. * Frequently the types and length of an ASN1_STRING are restricted by a * Frequently the types and length of an ASN1_STRING are restricted by a * corresponding OID. For example certificates and certificate requests. * corresponding OID. For example certificates and certificate requests. Loading @@ -78,12 +125,16 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, { { ASN1_STRING_TABLE *tbl; ASN1_STRING_TABLE *tbl; ASN1_STRING *str = NULL; ASN1_STRING *str = NULL; unsigned long mask; int ret; int ret; if(!out) out = &str; if(!out) out = &str; tbl = ASN1_STRING_TABLE_get(nid); tbl = ASN1_STRING_TABLE_get(nid); if(tbl) ret = ASN1_mbstring_ncopy(out, in, inlen, inform, tbl->mask, if(tbl) { mask = tbl->mask; if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask; ret = ASN1_mbstring_ncopy(out, in, inlen, inform, tbl->mask, tbl->minsize, tbl->maxsize); tbl->minsize, tbl->maxsize); else ret = ASN1_mbstring_copy(out, in, inlen, inform, 0); } else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask); if(ret <= 0) return NULL; if(ret <= 0) return NULL; return *out; return *out; } } Loading @@ -105,18 +156,18 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, /* This table must be kept in NID order */ /* This table must be kept in NID order */ static ASN1_STRING_TABLE tbl_standard[] = { static ASN1_STRING_TABLE tbl_standard[] = { {NID_commonName, 1, ub_common_name, 0, 0}, {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, 0}, {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_localityName, 1, ub_locality_name, 0, 0}, {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, {NID_stateOrProvinceName, 1, ub_state_name, 0, 0}, {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, {NID_organizationName, 1, ub_organization_name, 0, 0}, {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, {NID_organizationalUnitName, 1, ub_organization_unit_name, 0, 0}, {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0}, {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, 0}, {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK}, {NID_givenName, 1, ub_name, 0, 0}, {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_surname, 1, ub_name, 0, 0}, {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_initials, 1, ub_name, 0, 0}, {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_name, 1, ub_name, 0, 0}, {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, }; }; static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b) static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b) Loading Loading
CHANGES +25 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,31 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] Changes between 0.9.4 and 0.9.5 [xx XXX 1999] *) Initial changes to the 'req' utility to allow request generation automation. This will allow an application to just generate a template file containing all the field values and have req construct the request. Initial support for X509_ATTRIBUTE handling. Stacks of these are used all over the place including certificate requests and PKCS#7 structures. They are currently handled manually where necessary with some primitive wrappers for PKCS#7. The new functions behave in a manner analagous to the X509 extension functions: they allow attributes to be looked up by NID and added. Later something similar to the X509V3 code would be desirable to automatically handle the encoding, decoding and printing of the more complex types. The string types like challengePassword can be handled by the string table fuctions. Also modified the multi byte string table handling. Now there is a 'global mask' which masks out certain types. The table itself can use the flag STABLE_NO_MASK to ignore the mask setting: this is useful when for example there is only one permissible type (as in countryName) and using the mask might result in no valid types at all. [Steve Henson] *) Clean up 'Finished' handling, and add functions SSL_get_finished and *) Clean up 'Finished' handling, and add functions SSL_get_finished and SSL_get_peer_finished to allow applications to obtain the latest SSL_get_peer_finished to allow applications to obtain the latest Finished messages sent to the peer or expected from the peer, Finished messages sent to the peer or expected from the peer, Loading
apps/openssl.cnf +3 −4 Original line number Original line Diff line number Diff line Loading @@ -95,16 +95,15 @@ x509_extensions = v3_ca # The extentions to add to the self signed cert # input_password = secret # input_password = secret # output_password = secret # output_password = secret # This sets the permitted types in a DirectoryString. There are several # This sets a mask for permitted string types. There are several options. # options. # default: PrintableString, T61String, BMPString. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString. # pkix : PrintableString, BMPString. # utf8only: only UTF8Strings. # utf8only: only UTF8Strings. # nobmp : PrintableString, T61String (no BMPStrings). # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # MASK:XXXX a literal mask value. # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings # so use this option with caution! # so use this option with caution! dirstring_type = nobmp string_mask = nombstr # req_extensions = v3_req # The extensions to add to a certificate request # req_extensions = v3_req # The extensions to add to a certificate request Loading
apps/req.c +247 −26 Original line number Original line Diff line number Diff line Loading @@ -78,11 +78,12 @@ #define BITS "default_bits" #define BITS "default_bits" #define KEYFILE "default_keyfile" #define KEYFILE "default_keyfile" #define PROMPT "prompt" #define DISTINGUISHED_NAME "distinguished_name" #define DISTINGUISHED_NAME "distinguished_name" #define ATTRIBUTES "attributes" #define ATTRIBUTES "attributes" #define V3_EXTENSIONS "x509_extensions" #define V3_EXTENSIONS "x509_extensions" #define REQ_EXTENSIONS "req_extensions" #define REQ_EXTENSIONS "req_extensions" #define DIRSTRING_TYPE "dirstring_type" #define STRING_MASK "string_mask" #define DEFAULT_KEY_LENGTH 512 #define DEFAULT_KEY_LENGTH 512 #define MIN_KEY_LENGTH 384 #define MIN_KEY_LENGTH 384 Loading @@ -109,6 +110,11 @@ */ */ static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs); static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, STACK_OF(CONF_VALUE) *attr, int attribs); static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text, static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text, char *def, char *value, int nid, int min, char *def, char *value, int nid, int min, int max); int max); Loading Loading @@ -491,10 +497,10 @@ bad: if(!passout) if(!passout) passout = CONF_get_string(req_conf, SECTION, "output_password"); passout = CONF_get_string(req_conf, SECTION, "output_password"); p = CONF_get_string(req_conf, SECTION, DIRSTRING_TYPE); p = CONF_get_string(req_conf, SECTION, STRING_MASK); if(p && !ASN1_STRING_set_default_mask_asc(p)) { if(p && !ASN1_STRING_set_default_mask_asc(p)) { BIO_printf(bio_err, "Invalid DiretoryString setting %s", p); BIO_printf(bio_err, "Invalid global string mask setting %s", p); goto end; goto end; } } Loading Loading @@ -892,46 +898,47 @@ end: static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) { { int ret=0,i; int ret=0,i; char *p,*q; char no_prompt = 0; X509_REQ_INFO *ri; STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; char buf[100]; char *tmp, *dn_sect,*attr_sect; int nid,min,max; char *type,*def,*tmp,*value,*tmp_attr; tmp=CONF_get_string(req_conf,SECTION,PROMPT); STACK_OF(CONF_VALUE) *sk, *attr=NULL; if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1; CONF_VALUE *v; tmp=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); dn_sect=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); if (tmp == NULL) if (dn_sect == NULL) { { BIO_printf(bio_err,"unable to find '%s' in config\n", BIO_printf(bio_err,"unable to find '%s' in config\n", DISTINGUISHED_NAME); DISTINGUISHED_NAME); goto err; goto err; } } sk=CONF_get_section(req_conf,tmp); dn_sk=CONF_get_section(req_conf,dn_sect); if (sk == NULL) if (dn_sk == NULL) { { BIO_printf(bio_err,"unable to get '%s' section\n",tmp); BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect); goto err; goto err; } } tmp_attr=CONF_get_string(req_conf,SECTION,ATTRIBUTES); attr_sect=CONF_get_string(req_conf,SECTION,ATTRIBUTES); if (tmp_attr == NULL) if (attr_sect == NULL) attr=NULL; attr_sk=NULL; else else { { attr=CONF_get_section(req_conf,tmp_attr); attr_sk=CONF_get_section(req_conf,attr_sect); if (attr == NULL) if (attr_sk == NULL) { { BIO_printf(bio_err,"unable to get '%s' section\n",tmp_attr); BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect); goto err; goto err; } } } } ri=req->req_info; /* setup version number */ /* setup version number */ if (!ASN1_INTEGER_set(ri->version,0L)) goto err; /* version 1 */ if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */ if(no_prompt) i = auto_info(req, dn_sk, attr_sk, attribs); else i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs); if(!i) goto err; #if 0 BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); 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,"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"); BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); Loading Loading @@ -1039,7 +1046,7 @@ start2: for (;;) BIO_printf(bio_err,"No template, please set one up.\n"); BIO_printf(bio_err,"No template, please set one up.\n"); goto err; goto err; } } #endif X509_REQ_set_pubkey(req,pkey); X509_REQ_set_pubkey(req,pkey); ret=1; ret=1; Loading @@ -1047,6 +1054,220 @@ err: return(ret); return(ret); } } static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs) { int i; char *p,*q; char buf[100]; int nid,min,max; char *type,*def,*value; CONF_VALUE *v; X509_NAME *subj; subj = X509_REQ_get_subject_name(req); 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"); BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n"); BIO_printf(bio_err,"For some fields there will be a default value,\n"); BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); BIO_printf(bio_err,"-----\n"); if (sk_CONF_VALUE_num(dn_sk)) { i= -1; start: for (;;) { i++; if (sk_CONF_VALUE_num(dn_sk) <= i) break; v=sk_CONF_VALUE_value(dn_sk,i); p=q=NULL; type=v->name; if(!check_end(type,"_min") || !check_end(type,"_max") || !check_end(type,"_default") || !check_end(type,"_value")) continue; /* Skip past any leading X. X: X, etc to allow for * multiple instances */ for(p = v->name; *p ; p++) if ((*p == ':') || (*p == ',') || (*p == '.')) { p++; if(*p) type = p; break; } /* If OBJ not recognised ignore it */ if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start; sprintf(buf,"%s_default",v->name); if ((def=CONF_get_string(req_conf,dn_sect,buf)) == NULL) def=""; sprintf(buf,"%s_value",v->name); if ((value=CONF_get_string(req_conf,dn_sect,buf)) == NULL) value=NULL; sprintf(buf,"%s_min",v->name); min=(int)CONF_get_number(req_conf,dn_sect,buf); sprintf(buf,"%s_max",v->name); max=(int)CONF_get_number(req_conf,dn_sect,buf); if (!add_DN_object(subj,v->value,def,value,nid, min,max)) return 0; } if (X509_NAME_entry_count(subj) == 0) { BIO_printf(bio_err,"error, no objects specified in config file\n"); return 0; } if (attribs) { if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)) { BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); BIO_printf(bio_err,"to be sent with your certificate request\n"); } i= -1; start2: for (;;) { i++; if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) break; v=sk_CONF_VALUE_value(attr_sk,i); type=v->name; if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start2; sprintf(buf,"%s_default",type); if ((def=CONF_get_string(req_conf,attr_sect,buf)) == NULL) def=""; sprintf(buf,"%s_value",type); if ((value=CONF_get_string(req_conf,attr_sect,buf)) == NULL) value=NULL; sprintf(buf,"%s_min",type); min=(int)CONF_get_number(req_conf,attr_sect,buf); sprintf(buf,"%s_max",type); max=(int)CONF_get_number(req_conf,attr_sect,buf); if (!add_attribute_object(req->req_info->attributes, v->value,def,value,nid,min,max)) return 0; } } } else { BIO_printf(bio_err,"No template, please set one up.\n"); return 0; } return 1; } static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, STACK_OF(CONF_VALUE) *attr_sk, int attribs) { int i; char *p,*q; char *type; CONF_VALUE *v; X509_NAME *subj; subj = X509_REQ_get_subject_name(req); for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { v=sk_CONF_VALUE_value(dn_sk,i); p=q=NULL; type=v->name; /* Skip past any leading X. X: X, etc to allow for * multiple instances */ for(p = v->name; *p ; p++) if ((*p == ':') || (*p == ',') || (*p == '.')) { p++; if(*p) type = p; break; } if (!X509_NAME_add_entry_by_txt(subj,type, MBSTRING_ASC, (unsigned char *) v->value,-1,-1,0)) return 0; } if (!X509_NAME_entry_count(subj)) { BIO_printf(bio_err,"error, no objects specified in config file\n"); return 0; } #if 0 if (attribs) { if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)) { BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); BIO_printf(bio_err,"to be sent with your certificate request\n"); } i= -1; start2: for (;;) { i++; if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) break; v=sk_CONF_VALUE_value(attr_sk,i); type=v->name; if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start2; sprintf(buf,"%s_default",type); if ((def=CONF_get_string(req_conf,attr_sect,buf)) == NULL) def=""; sprintf(buf,"%s_value",type); if ((value=CONF_get_string(req_conf,attr_sect,buf)) == NULL) value=NULL; sprintf(buf,"%s_min",type); min=(int)CONF_get_number(req_conf,attr_sect,buf); sprintf(buf,"%s_max",type); max=(int)CONF_get_number(req_conf,attr_sect,buf); if (!add_attribute_object(ri->attributes, v->value,def,value,nid,min,max)) return 0; } } } else { BIO_printf(bio_err,"No template, please set one up.\n"); return 0; } #endif return 1; } static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, int nid, int min, int max) int nid, int min, int max) { { Loading
crypto/asn1/a_mbstr.c +1 −49 Original line number Original line Diff line number Diff line Loading @@ -72,54 +72,6 @@ static int cpy_univ(unsigned long value, void *arg); static int cpy_utf8(unsigned long value, void *arg); static int cpy_utf8(unsigned long value, void *arg); static int is_printable(unsigned long value); static int is_printable(unsigned long value); /* This is the default mask for the mbstring functions: it is designed * to be a "safe" DirectoryString. Netscape messenger crashes when it * receives a certificate containing a BMPString so by default we don't * use them unless we have to. */ static long dirstring_mask = B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_BMPSTRING; void ASN1_STRING_set_default_mask(unsigned long mask) { dirstring_mask = mask; } 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 /* 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 * a mask of permissible ASN1 string types. It then works out the minimal * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) Loading Loading @@ -147,7 +99,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, char strbuf[32]; char strbuf[32]; int (*cpyfunc)(unsigned long,void *) = NULL; int (*cpyfunc)(unsigned long,void *) = NULL; if(len == -1) len = strlen((const char *)in); if(len == -1) len = strlen((const char *)in); if(!mask) mask = dirstring_mask; if(!mask) mask = DIRSTRING_TYPE; /* First do a string check and work out the number of characters */ /* First do a string check and work out the number of characters */ switch(inform) { switch(inform) { Loading
crypto/asn1/a_strnid.c +65 −14 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,53 @@ static void st_free(ASN1_STRING_TABLE *tbl); static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b); static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b); static int table_cmp(ASN1_STRING_TABLE *a, ASN1_STRING_TABLE *b); static int table_cmp(ASN1_STRING_TABLE *a, ASN1_STRING_TABLE *b); /* This is the global mask for the mbstring functions: this is use to * mask out certain types (such as BMPString and UTF8String) because * certain software (e.g. Netscape) has problems with them. */ static long global_mask = 0xFFFFFFFFL; void ASN1_STRING_set_default_mask(unsigned long mask) { global_mask = mask; } unsigned long ASN1_STRING_get_default_mask(void) { return global_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, "nombchar")) mask = ~(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING); else if(!strcmp(p, "pkix")) mask = ~B_ASN1_T61STRING; else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING; else if(!strcmp(p, "default")) mask = 0xFFFFFFFFL; else return 0; ASN1_STRING_set_default_mask(mask); return 1; } /* The following function generates an ASN1_STRING based on limits in a table. /* The following function generates an ASN1_STRING based on limits in a table. * Frequently the types and length of an ASN1_STRING are restricted by a * Frequently the types and length of an ASN1_STRING are restricted by a * corresponding OID. For example certificates and certificate requests. * corresponding OID. For example certificates and certificate requests. Loading @@ -78,12 +125,16 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, { { ASN1_STRING_TABLE *tbl; ASN1_STRING_TABLE *tbl; ASN1_STRING *str = NULL; ASN1_STRING *str = NULL; unsigned long mask; int ret; int ret; if(!out) out = &str; if(!out) out = &str; tbl = ASN1_STRING_TABLE_get(nid); tbl = ASN1_STRING_TABLE_get(nid); if(tbl) ret = ASN1_mbstring_ncopy(out, in, inlen, inform, tbl->mask, if(tbl) { mask = tbl->mask; if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask; ret = ASN1_mbstring_ncopy(out, in, inlen, inform, tbl->mask, tbl->minsize, tbl->maxsize); tbl->minsize, tbl->maxsize); else ret = ASN1_mbstring_copy(out, in, inlen, inform, 0); } else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask); if(ret <= 0) return NULL; if(ret <= 0) return NULL; return *out; return *out; } } Loading @@ -105,18 +156,18 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, /* This table must be kept in NID order */ /* This table must be kept in NID order */ static ASN1_STRING_TABLE tbl_standard[] = { static ASN1_STRING_TABLE tbl_standard[] = { {NID_commonName, 1, ub_common_name, 0, 0}, {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, 0}, {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_localityName, 1, ub_locality_name, 0, 0}, {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, {NID_stateOrProvinceName, 1, ub_state_name, 0, 0}, {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, {NID_organizationName, 1, ub_organization_name, 0, 0}, {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, {NID_organizationalUnitName, 1, ub_organization_unit_name, 0, 0}, {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0}, {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, 0}, {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK}, {NID_givenName, 1, ub_name, 0, 0}, {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_surname, 1, ub_name, 0, 0}, {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_initials, 1, ub_name, 0, 0}, {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_name, 1, ub_name, 0, 0}, {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, }; }; static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b) static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b) Loading