X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=apps%2Fca.c;h=0fd445613d4ff25e62571afb5a3c7c8e6a0b7e93;hb=3205db2bfecdd83d321455a6302628f39b336be4;hp=2c7e91aabb3c6ea860b85f82bc71c4b3e9cd3015;hpb=fd4ef699133e445e8224f68d39cc155ea4a26c1a;p=openssl.git diff --git a/apps/ca.c b/apps/ca.c index 2c7e91aabb..0fd445613d 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -76,16 +76,6 @@ #include #include -#ifdef OPENSSL_SYS_WINDOWS -#define strcasecmp _stricmp -#else -# ifdef NO_STRINGS_H - int strcasecmp(); -# else -# include -# endif /* NO_STRINGS_H */ -#endif - #ifndef W_OK # ifdef OPENSSL_SYS_VMS # if defined(__DECC) @@ -93,7 +83,7 @@ # else # include # endif -# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) +# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE) # include # endif #endif @@ -141,6 +131,7 @@ #define ENV_NAMEOPT "name_opt" #define ENV_CERTOPT "cert_opt" #define ENV_EXTCOPY "copy_extensions" +#define ENV_UNIQUE_SUBJECT "unique_subject" #define ENV_DATABASE "database" @@ -183,6 +174,7 @@ static char *ca_usage[]={ " -msie_hack - msie modifications to handle all those universal strings\n", " -revoke file - Revoke a certificate (given in file)\n", " -subj arg - Use arg instead of request's subject\n", +" -multivalue-rdn - enable support for multivalued RDNs\n", " -extensions .. - Extension section (override value in config file)\n", " -extfile file - Configuration file with X509v3 extentions to add\n", " -crlexts .. - CRL extension section (override value in config file)\n", @@ -203,27 +195,27 @@ extern int EF_ALIGNMENT; static void lookup_fail(char *name,char *tag); static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db, - BIGNUM *serial, char *subj, int email_dn, char *startdate, + BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, int batch, char *ext_sect, CONF *conf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, int selfsign); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, - CA_DB *db, BIGNUM *serial, char *subj, int email_dn, + CA_DB *db, BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, int batch, char *ext_sect, CONF *conf,int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, ENGINE *e); static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, - CA_DB *db, BIGNUM *serial,char *subj, int email_dn, + CA_DB *db, BIGNUM *serial,char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, char *ext_sect, CONF *conf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy); static int fix_data(int nid, int *type); static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, - STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj, + STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, int batch, int verbose, X509_REQ *req, char *ext_sect, CONF *conf, unsigned long certopt, unsigned long nameopt, int default_op, @@ -249,6 +241,7 @@ int MAIN(int argc, char **argv) { ENGINE *e = NULL; char *key=NULL,*passargin=NULL; + int create_ser = 0; int free_key = 0; int total=0; int total_done=0; @@ -282,6 +275,7 @@ int MAIN(int argc, char **argv) char *extensions=NULL; char *extfile=NULL; char *subj=NULL; + int multirdn = 0; char *tmp_email_dn=NULL; char *crl_ext=NULL; int rev_type = REV_NONE; @@ -361,6 +355,10 @@ EF_ALIGNMENT=0; subj= *(++argv); /* preserve=1; */ } + else if (strcmp(*argv,"-create_serial") == 0) + create_ser = 1; + else if (strcmp(*argv,"-multivalue-rdn") == 0) + multirdn=1; else if (strcmp(*argv,"-startdate") == 0) { if (--argc < 1) goto bad; @@ -562,16 +560,19 @@ bad: if (configfile == NULL) { const char *s=X509_get_default_cert_area(); + size_t len; #ifdef OPENSSL_SYS_VMS - tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)); + len = strlen(s)+sizeof(CONFIG_FILE); + tofree=OPENSSL_malloc(len); strcpy(tofree,s); #else - tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1); - strcpy(tofree,s); - strcat(tofree,"/"); + len = strlen(s)+sizeof(CONFIG_FILE)+1; + tofree=OPENSSL_malloc(len); + BUF_strlcpy(tofree,s,len); + BUF_strlcat(tofree,"/",len); #endif - strcat(tofree,CONFIG_FILE); + BUF_strlcat(tofree,CONFIG_FILE,len); configfile=tofree; } @@ -644,31 +645,18 @@ bad: app_RAND_load_file(randfile, bio_err, 0); db_attr.unique_subject = 1; - p = NCONF_get_string(conf, section, "unique_subject"); + p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT); if (p) { #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p); #endif - switch(*p) - { - case 'f': /* false */ - case 'F': /* FALSE */ - case 'n': /* no */ - case 'N': /* NO */ - db_attr.unique_subject = 0; - break; - case 't': /* true */ - case 'T': /* TRUE */ - case 'y': /* yes */ - case 'Y': /* YES */ - default: - db_attr.unique_subject = 1; - break; - } + db_attr.unique_subject = parse_yesno(p,1); } -#ifdef RL_DEBUG else + ERR_clear_error(); +#ifdef RL_DEBUG + if (!p) BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p); #endif #ifdef RL_DEBUG @@ -1112,7 +1100,7 @@ bad: goto err; } - if ((serial=load_serial(serialfile, 0, NULL)) == NULL) + if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL) { BIO_printf(bio_err,"error while loading serial number\n"); goto err; @@ -1144,7 +1132,7 @@ bad: { total++; j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, - serial,subj,email_dn,startdate,enddate,days,extensions, + serial,subj,multirdn,email_dn,startdate,enddate,days,extensions, conf,verbose,certopt,nameopt,default_op,ext_copy); if (j < 0) goto err; if (j > 0) @@ -1168,7 +1156,7 @@ bad: { total++; j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, - db,serial,subj,email_dn,startdate,enddate,days,batch, + db,serial,subj,multirdn,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy, e); if (j < 0) goto err; @@ -1188,7 +1176,7 @@ bad: { total++; j=certify(&x,infile,pkey,x509p,dgst,attribs,db, - serial,subj,email_dn,startdate,enddate,days,batch, + serial,subj,multirdn,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy, selfsign); if (j < 0) goto err; @@ -1208,7 +1196,7 @@ bad: { total++; j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db, - serial,subj,email_dn,startdate,enddate,days,batch, + serial,subj,multirdn,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy, selfsign); if (j < 0) goto err; @@ -1256,7 +1244,7 @@ bad: for (i=0; i 0) { for (k=0; k= &(buf[2][sizeof(buf[2])])) + break; + BIO_snprintf(n, + &buf[2][0] + sizeof(buf[2]) - n, + "%02X",(unsigned char)*(p++)); n+=2; } } @@ -1527,7 +1519,7 @@ static void lookup_fail(char *name, char *tag) static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, + BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, int batch, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, int selfsign) @@ -1583,7 +1575,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, else BIO_printf(bio_err,"Signature ok\n"); - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, multirdn, email_dn, startdate,enddate,days,batch,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, ext_copy, selfsign); @@ -1595,7 +1587,7 @@ err: static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, + BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, int batch, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, ENGINE *e) @@ -1637,7 +1629,7 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL) goto err; - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,multirdn,email_dn,startdate,enddate, days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0); @@ -1649,6 +1641,7 @@ err: static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj, + int multirdn, int email_dn, char *startdate, char *enddate, long days, int batch, int verbose, X509_REQ *req, char *ext_sect, CONF *lconf, unsigned long certopt, unsigned long nameopt, int default_op, @@ -1681,7 +1674,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, if (subj) { - X509_NAME *n = do_subject(subj, MBSTRING_ASC); + X509_NAME *n = parse_name(subj, MBSTRING_ASC, multirdn); if (!n) { @@ -2146,7 +2139,7 @@ again2: BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } - strcpy(row[DB_file],"unknown"); + BUF_strlcpy(row[DB_file],"unknown",8); row[DB_type][0]='V'; row[DB_type][1]='\0'; @@ -2218,7 +2211,7 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, + BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate, long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) { @@ -2359,7 +2352,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, X509_REQ_set_pubkey(req,pktmp); EVP_PKEY_free(pktmp); - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,multirdn,email_dn,startdate,enddate, days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0); err: @@ -2447,7 +2440,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } - strcpy(row[DB_file],"unknown"); + BUF_strlcpy(row[DB_file],"unknown",8); row[DB_type][0]='V'; row[DB_type][1]='\0'; @@ -2771,16 +2764,16 @@ char *make_revocation_str(int rev_type, char *rev_arg) if (!str) return NULL; - strcpy(str, (char *)revtm->data); + BUF_strlcpy(str, (char *)revtm->data, i); if (reason) { - strcat(str, ","); - strcat(str, reason); + BUF_strlcat(str, ",", i); + BUF_strlcat(str, reason, i); } if (other) { - strcat(str, ","); - strcat(str, other); + BUF_strlcat(str, ",", i); + BUF_strlcat(str, other, i); } ASN1_UTCTIME_free(revtm); return str; @@ -2848,129 +2841,6 @@ int make_revoked(X509_REVOKED *rev, char *str) return ret; } -/* - * subject is expected to be in the format /type0=value0/type1=value1/type2=... - * where characters may be escaped by \ - */ -X509_NAME *do_subject(char *subject, long chtype) - { - size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ - char *buf = OPENSSL_malloc(buflen); - size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ - char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *)); - char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *)); - - char *sp = subject, *bp = buf; - int i, ne_num = 0; - - X509_NAME *n = NULL; - int nid; - - if (!buf || !ne_types || !ne_values) - { - BIO_printf(bio_err, "malloc error\n"); - goto error; - } - - if (*subject != '/') - { - BIO_printf(bio_err, "Subject does not start with '/'.\n"); - goto error; - } - sp++; /* skip leading / */ - - while (*sp) - { - /* collect type */ - ne_types[ne_num] = bp; - while (*sp) - { - if (*sp == '\\') /* is there anything to escape in the type...? */ - { - if (*++sp) - *bp++ = *sp++; - else - { - BIO_printf(bio_err, "escape character at end of string\n"); - goto error; - } - } - else if (*sp == '=') - { - sp++; - *bp++ = '\0'; - break; - } - else - *bp++ = *sp++; - } - if (!*sp) - { - BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num); - goto error; - } - ne_values[ne_num] = bp; - while (*sp) - { - if (*sp == '\\') - { - if (*++sp) - *bp++ = *sp++; - else - { - BIO_printf(bio_err, "escape character at end of string\n"); - goto error; - } - } - else if (*sp == '/') - { - sp++; - break; - } - else - *bp++ = *sp++; - } - *bp++ = '\0'; - ne_num++; - } - - if (!(n = X509_NAME_new())) - goto error; - - for (i = 0; i < ne_num; i++) - { - if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) - { - BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); - continue; - } - - if (!*ne_values[i]) - { - BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]); - continue; - } - - if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0)) - goto error; - } - - OPENSSL_free(ne_values); - OPENSSL_free(ne_types); - OPENSSL_free(buf); - return n; - -error: - X509_NAME_free(n); - if (ne_values) - OPENSSL_free(ne_values); - if (ne_types) - OPENSSL_free(ne_types); - if (buf) - OPENSSL_free(buf); - return NULL; -} - int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) { char buf[25],*pbuf, *p; @@ -3015,7 +2885,8 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_G char *tmp = NULL; char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p; int reason_code = -1; - int i, ret = 0; + int ret = 0; + unsigned int i; ASN1_OBJECT *hold = NULL; ASN1_GENERALIZEDTIME *comp_time = NULL; tmp = BUF_strdup(str);