diff --git a/CHANGES b/CHANGES index 535d56d072..ecfb0c01a3 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,18 @@ Changes between 0.9.2b and 0.9.3 + *) Allow PKCS#12 password to be set from the command line or the + environment. Let 'ca' get its config file name from the environment + variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req' + and 'x509'). + [Steve Henson] + + *) Allow certificate policies extension to use an IA5STRING for the + organization field. This is contrary to the PKIX definition but + VeriSign uses it and IE5 only recognises this form. Document 'x509' + extension option. + [Steve Henson] + *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic, without disallowing inline assembler and the like for non-pedantic builds. [Ben Laurie] diff --git a/apps/ca.c b/apps/ca.c index efcd817311..323eb8525f 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -390,6 +390,8 @@ bad: ERR_load_crypto_strings(); /*****************************************************************/ + if (configfile == NULL) configfile = getenv("OPENSSL_CONF"); + if (configfile == NULL) configfile = getenv("SSLEAY_CONF"); if (configfile == NULL) { /* We will just use 'buf[0]' as a temporary buffer. */ diff --git a/apps/pkcs12.c b/apps/pkcs12.c index b056b84172..ab600624d1 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -105,7 +105,9 @@ int MAIN(int argc, char **argv) int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; int ret = 1; int macver = 1; + int noprompt = 0; STACK *canames = NULL; + char *cpass = NULL, *mpass = NULL; apps_startup(); @@ -170,6 +172,22 @@ int MAIN(int argc, char **argv) args++; outfile = *args; } else badarg = 1; + } else if (!strcmp (*args, "-envpass")) { + if (args[1]) { + args++; + if(!(cpass = getenv(*args))) { + BIO_printf(bio_err, + "Can't read environment variable %s\n", *args); + goto end; + } + noprompt = 1; + } else badarg = 1; + } else if (!strcmp (*args, "-password")) { + if (args[1]) { + args++; + cpass = *args; + noprompt = 1; + } else badarg = 1; } else badarg = 1; } else badarg = 1; @@ -206,9 +224,17 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); BIO_printf (bio_err, "-keyex set MS key exchange type\n"); BIO_printf (bio_err, "-keysig set MS key signature type\n"); + BIO_printf (bio_err, "-password p set import/export password (NOT RECOMMENDED)\n"); + BIO_printf (bio_err, "-envpass p set import/export password from environment\n"); goto end; } + if(cpass) mpass = cpass; + else { + cpass = pass; + mpass = macpass; + } + ERR_load_crypto_strings(); in = BIO_new (BIO_s_file()); @@ -344,13 +370,14 @@ if (export_cert) { if (canames) sk_free(canames); - if(EVP_read_pw_string (pass, 50, "Enter Export Password:", 1)) { + if(!noprompt && + EVP_read_pw_string(pass, 50, "Enter Export Password:", 1)) { BIO_printf (bio_err, "Can't read Password\n"); goto end; } if (!twopass) strcpy(macpass, pass); /* Turn certbags into encrypted authsafe */ - authsafe = PKCS12_pack_p7encdata (cert_pbe, pass, -1, NULL, 0, + authsafe = PKCS12_pack_p7encdata (cert_pbe, cpass, -1, NULL, 0, iter, bags); sk_pop_free(bags, PKCS12_SAFEBAG_free); @@ -367,7 +394,7 @@ if (export_cert) { EVP_PKEY_free(key); if(keytype) PKCS8_add_keyusage(p8, keytype); bag = PKCS12_MAKE_SHKEYBAG (NID_pbe_WithSHA1And3_Key_TripleDES_CBC, - pass, -1, NULL, 0, iter, p8); + cpass, -1, NULL, 0, iter, p8); PKCS8_PRIV_KEY_INFO_free(p8); if (name) PKCS12_add_friendlyname (bag, name, -1); PKCS12_add_localkeyid (bag, keyid, keyidlen); @@ -384,7 +411,7 @@ if (export_cert) { sk_pop_free(safes, PKCS7_free); - PKCS12_set_mac (p12, macpass, -1, NULL, 0, maciter, NULL); + PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL); i2d_PKCS12_bio (out, p12); @@ -400,7 +427,7 @@ if (export_cert) { goto end; } - if(EVP_read_pw_string (pass, 50, "Enter Import Password:", 0)) { + if(!noprompt && EVP_read_pw_string(pass, 50, "Enter Import Password:", 0)) { BIO_printf (bio_err, "Can't read Password\n"); goto end; } @@ -409,14 +436,14 @@ if (export_cert) { if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { - if (!PKCS12_verify_mac (p12, macpass, -1)) { + if (!PKCS12_verify_mac (p12, mpass, -1)) { BIO_printf (bio_err, "Mac verify errror: invalid password?\n"); ERR_print_errors (bio_err); goto end; } else BIO_printf (bio_err, "MAC verified OK\n"); } - if (!dump_certs_keys_p12 (out, p12, pass, -1, options)) { + if (!dump_certs_keys_p12 (out, p12, cpass, -1, options)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors (bio_err); goto end; diff --git a/crypto/x509v3/v3_cpols.c b/crypto/x509v3/v3_cpols.c index 3580ffd14f..94d4cdbec7 100644 --- a/crypto/x509v3/v3_cpols.c +++ b/crypto/x509v3/v3_cpols.c @@ -69,8 +69,8 @@ static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value); static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent); static void print_notice(BIO *out, USERNOTICE *notice, int indent); -static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs); -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot); +static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs, int ia5org); +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot, int ia5org); static STACK *nref_nos(STACK *nos); X509V3_EXT_METHOD v3_cpols = { @@ -96,9 +96,10 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, ASN1_OBJECT *pobj; STACK *vals; CONF_VALUE *cnf; - int i; + int i, ia5org; pols = sk_POLICYINFO_new_null(); vals = X509V3_parse_list(value); + ia5org = 0; for(i = 0; i < sk_num(vals); i++) { cnf = (CONF_VALUE *)sk_value(vals, i); if(cnf->value || !cnf->name ) { @@ -107,7 +108,10 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, goto err; } pstr = cnf->name; - if(*pstr == '@') { + if(!strcmp(pstr,"ia5org")) { + ia5org = 1; + continue; + } else if(*pstr == '@') { STACK *polsect; polsect = X509V3_get_section(ctx, pstr + 1); if(!polsect) { @@ -116,7 +120,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_conf_err(cnf); goto err; } - pol = policy_section(ctx, polsect); + pol = policy_section(ctx, polsect, ia5org); X509V3_section_free(ctx, polsect); if(!pol) goto err; } else { @@ -137,7 +141,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, return NULL; } -static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs) +static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs, int ia5org) { int i; CONF_VALUE *cnf; @@ -179,7 +183,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs) X509V3_conf_err(cnf); goto err; } - qual = notice_section(ctx, unot); + qual = notice_section(ctx, unot, ia5org); X509V3_section_free(ctx, unot); if(!qual) goto err; if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) @@ -208,7 +212,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK *polstrs) } -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot) +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot, int ia5org) { int i; CONF_VALUE *cnf; @@ -230,7 +234,8 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, STACK *unot) if(!(nref = NOTICEREF_new())) goto merr; not->noticeref = nref; } else nref = not->noticeref; - nref->organization = ASN1_VISIBLESTRING_new(); + if(ia5org) nref->organization = ASN1_IA5STRING_new(); + else nref->organization = ASN1_VISIBLESTRING_new(); if(!ASN1_STRING_set(nref->organization, cnf->value, strlen(cnf->value))) goto merr; } else if(!strcmp(cnf->name, "noticeNumbers")) { diff --git a/doc/openssl.txt b/doc/openssl.txt index 76f49132f0..a90c49573b 100644 --- a/doc/openssl.txt +++ b/doc/openssl.txt @@ -98,6 +98,15 @@ indicates which section contains the extensions. In the case of 'req' the extension section is used when the -x509 option is present to create a self signed root certificate. +The 'x509' utility also supports extensions when it signs a certificate. +The -config option is used to set the configuration file containing the +extensions. In this case a line with: + +extensions = extension_section + +in the nameless (default) section is used. If no such line is include then +it uses the default section. + You can also add extensions to CRLs: a line crl_extensions = crl_extension_section @@ -108,6 +117,17 @@ issuerAltName and authorityKeyIdentifier make any real sense. Note: these are CRL extensions NOT CRL *entry* extensions which cannot currently be generated. CRL entry extensions can be displayed. +NB. At this time Netscape Communicator rejects V2 CRLs: to get an old V1 CRL +you should comment out the crl_extensions line in the configuration file. + +As with all configuration files you can use the inbuilt environment expansion +to allow the values to be passed in the environment. Therefore if you have +several extension sections used for different purposes you can have a line: + +x509_extensions = $ENV::ENV_EXT + +and set the ENV_EXT environment variable before calling the relevant utility. + EXTENSION SYNTAX. Extensions have the basic form: @@ -298,7 +318,10 @@ This is a RAW extension. It attempts to display the contents of this extension: unfortuntately this extension is often improperly encoded. The certificate policies extension will rarely be used in practice: few -software packages interpret it correctly or at all. +software packages interpret it correctly or at all. IE5 does partially +support this extension: but it needs the 'ia5org' option because it will +only correctly support a broken encoding. Of the options below only the +policy OID, explicitText and CPS options are displayed with IE5. All the fields of this extension can be set by using the appropriate syntax. @@ -325,11 +348,13 @@ The value of the userNotice qualifier is specified in the relevant section. This section can include explicitText, organization and noticeNumbers options. explicitText and organization are text strings, noticeNumbers is a comma separated list of numbers. The organization and noticeNumbers options (if -included) must BOTH be present. +included) must BOTH be present. If you use the userNotice option with IE5 then +you need the 'ia5org' option at the top level to modify the encoding: otherwise +it will not be interpreted properly. Example: -certificatePolicies=1.2.3.4,1.5.6.7.8,@polsect +certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect [polsect] @@ -344,6 +369,10 @@ explicitText="Explicit Text Here" organization="Organisation Name" noticeNumbers=1,2,3,4 +TECHNICAL NOTE: the ia5org option changes the type of the 'organization' field, +according to PKIX it should be of type DisplayText but Verisign uses an +IA5STRING and IE5 needs this too. + Display only extensions. Some extensions are only partially supported and currently are only displayed @@ -374,7 +403,8 @@ private key and certificate pair. No special initialisation is needed for the internal PKCS#12 library: the standard SSLeay_add_all_algorithms() is sufficient. If you do not wish to -add all algorithms then you can manually initialise the PKCS#12 library with: +add all algorithms (you should at least add SHA1 though) then you can manually +initialise the PKCS#12 library with: PKSC12_PBE_add();