X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=apps%2Fca.c;h=39956e89a44692abdc2d7bb1544da279be5be0a3;hb=153aecf91a9d11ccbdf7dedc1051cb6c746f7d6e;hp=481bfc77d758412c543b41ef79ef886d29ed31d1;hpb=1372965e2ebed49c810978e00be50006f1d7219a;p=oweals%2Fopenssl.git diff --git a/apps/ca.c b/apps/ca.c index 481bfc77d7..39956e89a4 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -80,7 +80,11 @@ #ifdef OPENSSL_SYS_WINDOWS #define strcasecmp _stricmp #else -#include +# ifdef NO_STRINGS_H + int strcasecmp(); +# else +# include +# endif /* NO_STRINGS_H */ #endif #ifndef W_OK @@ -90,7 +94,7 @@ # else # include # endif -# else +# elif !defined(OPENSSL_SYS_VXWORKS) # include # endif #endif @@ -126,6 +130,7 @@ #define ENV_DEFAULT_CRL_DAYS "default_crl_days" #define ENV_DEFAULT_CRL_HOURS "default_crl_hours" #define ENV_DEFAULT_MD "default_md" +#define ENV_DEFAULT_EMAIL_DN "email_in_dn" #define ENV_PRESERVE "preserve" #define ENV_POLICY "policy" #define ENV_EXTENSIONS "x509_extensions" @@ -182,6 +187,7 @@ static char *ca_usage[]={ " -spkac file - File contains DN and signed public key and challenge\n", " -ss_cert file - File contains a self signed cert to sign\n", " -preserveDN - Don't re-order the DN\n", +" -noemailDN - Don't add the EMAIL field into certificate' subject\n", " -batch - Don't ask questions\n", " -msie_hack - msie modifications to handle all those universal strings\n", " -revoke file - Revoke a certificate (given in file)\n", @@ -211,32 +217,31 @@ static BIGNUM *load_serial(char *serialfile); static int save_serial(char *serialfile, BIGNUM *serial); static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db, - BIGNUM *serial, char *subj, 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); + BIGNUM *serial, char *subj, 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); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, - TXT_DB *db, BIGNUM *serial, char *subj, char *startdate, - char *enddate, long days, int batch, char *ext_sect, - CONF *conf,int verbose, unsigned long certopt, + TXT_DB *db, BIGNUM *serial, char *subj, 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, - TXT_DB *db, BIGNUM *serial,char *subj, 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); + TXT_DB *db, BIGNUM *serial,char *subj, 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, TXT_DB *db, BIGNUM *serial,char *subj, - char *startdate, char *enddate, long days, int batch, int verbose, - X509_REQ *req, char *ext_sect, CONF *conf, + 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, int ext_copy); -static X509_NAME *do_subject(char *subject); static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval); static int get_certificate_status(const char *ser_status, TXT_DB *db); static int do_updatedb(TXT_DB *db); @@ -268,6 +273,7 @@ int MAIN(int argc, char **argv) int total_done=0; int badops=0; int ret=1; + int email_dn=1; int req=0; int verbose=0; int gencrl=0; @@ -294,6 +300,7 @@ int MAIN(int argc, char **argv) char *extensions=NULL; char *extfile=NULL; char *subj=NULL; + char *tmp_email_dn=NULL; char *crl_ext=NULL; int rev_type = REV_NONE; char *rev_arg = NULL; @@ -439,6 +446,8 @@ EF_ALIGNMENT=0; batch=1; else if (strcmp(*argv,"-preserveDN") == 0) preserve=1; + else if (strcmp(*argv,"-noemailDN") == 0) + email_dn=0; else if (strcmp(*argv,"-gencrl") == 0) gencrl=1; else if (strcmp(*argv,"-msie_hack") == 0) @@ -565,6 +574,7 @@ bad: #else strncpy(buf[0],X509_get_default_cert_area(), sizeof(buf[0])-2-sizeof(CONFIG_FILE)); + buf[0][sizeof(buf[0])-2-sizeof(CONFIG_FILE)]='\0'; strcat(buf[0],"/"); #endif strcat(buf[0],CONFIG_FILE); @@ -584,6 +594,9 @@ bad: goto err; } + if (!load_config(bio_err, conf)) + goto err; + /* Lets get the config section we are using */ if (section == NULL) { @@ -686,7 +699,7 @@ bad: goto err; } } - pkey = load_key(bio_err, keyfile, keyform, key, e, + pkey = load_key(bio_err, keyfile, keyform, 0, key, e, "CA private key"); if (key) memset(key,0,strlen(key)); if (pkey == NULL) @@ -1041,6 +1054,12 @@ bad: lookup_fail(section,ENV_DEFAULT_MD); goto err; } + if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf, + section,ENV_DEFAULT_EMAIL_DN)) != NULL )) + { + if(strcmp(tmp_email_dn,"no") == 0) + email_dn=0; + } if ((dgst=EVP_get_digestbyname(md)) == NULL) { BIO_printf(bio_err,"%s is an unsupported message digest type\n",md); @@ -1159,8 +1178,8 @@ bad: { total++; j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, - serial,subj,startdate,enddate, days,extensions,conf, - verbose, certopt, nameopt, default_op, ext_copy); + serial,subj,email_dn,startdate,enddate,days,extensions, + conf,verbose,certopt,nameopt,default_op,ext_copy); if (j < 0) goto err; if (j > 0) { @@ -1183,7 +1202,7 @@ bad: { total++; j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, - db,serial,subj,startdate,enddate,days,batch, + db,serial,subj,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy, e); if (j < 0) goto err; @@ -1203,7 +1222,7 @@ bad: { total++; j=certify(&x,infile,pkey,x509,dgst,attribs,db, - serial,subj,startdate,enddate,days,batch, + serial,subj,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy); if (j < 0) goto err; @@ -1223,7 +1242,7 @@ bad: { total++; j=certify(&x,argv[i],pkey,x509,dgst,attribs,db, - serial,subj,startdate,enddate,days,batch, + serial,subj,email_dn,startdate,enddate,days,batch, extensions,conf,verbose, certopt, nameopt, default_op, ext_copy); if (j < 0) goto err; @@ -1262,6 +1281,7 @@ bad: BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk)); strncpy(buf[0],serialfile,BSIZE-4); + buf[0][BSIZE-4]='\0'; #ifdef OPENSSL_SYS_VMS strcat(buf[0],"-new"); @@ -1272,6 +1292,7 @@ bad: if (!save_serial(buf[0],serial)) goto err; strncpy(buf[1],dbfile,BSIZE-4); + buf[1][BSIZE-4]='\0'; #ifdef OPENSSL_SYS_VMS strcat(buf[1],"-new"); @@ -1302,6 +1323,7 @@ bad: p=(char *)x->cert_info->serialNumber->data; strncpy(buf[2],outdir,BSIZE-(j*2)-6); + buf[2][BSIZE-(j*2)-6]='\0'; #ifndef OPENSSL_SYS_VMS strcat(buf[2],"/"); @@ -1339,6 +1361,7 @@ bad: { /* Rename the database and the serial file */ strncpy(buf[2],serialfile,BSIZE-4); + buf[2][BSIZE-4]='\0'; #ifdef OPENSSL_SYS_VMS strcat(buf[2],"-old"); @@ -1367,6 +1390,7 @@ bad: } strncpy(buf[2],dbfile,BSIZE-4); + buf[2][BSIZE-4]='\0'; #ifdef OPENSSL_SYS_VMS strcat(buf[2],"-old"); @@ -1430,13 +1454,13 @@ bad: } if ((crldays == 0) && (crlhours == 0)) { - BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n"); + BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n"); goto err; } if (verbose) BIO_printf(bio_err,"making CRL\n"); if ((crl=X509_CRL_new()) == NULL) goto err; - if (!X509_CRL_set_issuer_name(crl, X509_get_issuer_name(x509))) goto err; + if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err; tmptm = ASN1_TIME_new(); if (!tmptm) goto err; @@ -1489,6 +1513,11 @@ bad: if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1(); else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) + dgst=EVP_ecdsa(); + else #endif dgst=EVP_md5(); } @@ -1534,6 +1563,7 @@ bad: X509_free(revcert); strncpy(buf[0],dbfile,BSIZE-4); + buf[0][BSIZE-4]='\0'; #ifndef OPENSSL_SYS_VMS strcat(buf[0],".new"); #else @@ -1548,11 +1578,16 @@ bad: j=TXT_DB_write(out,db); if (j <= 0) goto err; strncpy(buf[1],dbfile,BSIZE-4); + buf[1][BSIZE-4]='\0'; #ifndef OPENSSL_SYS_VMS strcat(buf[1],".old"); #else strcat(buf[1],"-old"); #endif + BIO_free(in); + in = NULL; + BIO_free(out); + out = NULL; if (rename(dbfile,buf[1]) < 0) { BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]); @@ -1699,8 +1734,8 @@ err: static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, - BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, - int batch, char *ext_sect, CONF *lconf, int verbose, + BIGNUM *serial, char *subj, 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) { @@ -1749,8 +1784,8 @@ 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,startdate, enddate, - days,batch,verbose,req,ext_sect,lconf, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn, + startdate,enddate,days,batch,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, ext_copy); err: @@ -1761,8 +1796,8 @@ err: static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, - BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, - int batch, char *ext_sect, CONF *lconf, int verbose, + BIGNUM *serial, char *subj, 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) { @@ -1803,9 +1838,9 @@ 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,startdate,enddate,days, - batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, - ext_copy); + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, + days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, + ext_copy); err: if (rreq != NULL) X509_REQ_free(rreq); @@ -1815,12 +1850,12 @@ err: static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj, - char *startdate, char *enddate, long days, int batch, int verbose, - X509_REQ *req, char *ext_sect, CONF *lconf, + 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, int ext_copy) { - X509_NAME *name=NULL,*CAname=NULL,*subject=NULL; + X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL; ASN1_UTCTIME *tm,*tmptm; ASN1_STRING *str,*str2; ASN1_OBJECT *obj; @@ -1847,7 +1882,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, if (subj) { - X509_NAME *n = do_subject(subj); + X509_NAME *n = do_subject(subj, MBSTRING_ASC); if (!n) { @@ -1861,6 +1896,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, if (default_op) BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n"); + name=X509_REQ_get_subject_name(req); for (i=0; itype=V_ASN1_IA5STRING; } + /* If no EMAIL is wanted in the subject */ + if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn)) + continue; + /* check some things */ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (str->type != V_ASN1_IA5STRING)) @@ -1892,14 +1932,17 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n"); goto err; } - j=ASN1_PRINTABLE_type(str->data,str->length); - if ( ((j == V_ASN1_T61STRING) && - (str->type != V_ASN1_T61STRING)) || - ((j == V_ASN1_IA5STRING) && - (str->type == V_ASN1_PRINTABLESTRING))) + if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING)) { - BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n"); - goto err; + j=ASN1_PRINTABLE_type(str->data,str->length); + if ( ((j == V_ASN1_T61STRING) && + (str->type != V_ASN1_T61STRING)) || + ((j == V_ASN1_IA5STRING) && + (str->type == V_ASN1_PRINTABLESTRING))) + { + BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n"); + goto err; + } } if (default_op) @@ -2018,16 +2061,41 @@ again2: if (preserve) { X509_NAME_free(subject); - subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); + /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ + subject=X509_NAME_dup(name); if (subject == NULL) goto err; } if (verbose) BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n"); - row[DB_name]=X509_NAME_oneline(subject,NULL,0); + /* Build the correct Subject if no e-mail is wanted in the subject */ + /* and add it later on because of the method extensions are added (altName) */ + + if (email_dn) + dn_subject = subject; + else + { + X509_NAME_ENTRY *tmpne; + /* Its best to dup the subject DN and then delete any email + * addresses because this retains its structure. + */ + if (!(dn_subject = X509_NAME_dup(subject))) + { + BIO_printf(bio_err,"Memory allocation failure\n"); + goto err; + } + while((i = X509_NAME_get_index_by_NID(dn_subject, + NID_pkcs9_emailAddress, -1)) >= 0) + { + tmpne = X509_NAME_get_entry(dn_subject, i); + X509_NAME_delete_entry(dn_subject, i); + X509_NAME_ENTRY_free(tmpne); + } + } + row[DB_serial]=BN_bn2hex(serial); - if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) + if (row[DB_serial] == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; @@ -2181,6 +2249,11 @@ again2: goto err; } + /* Set the right value for the noemailDN option */ + if( email_dn == 0 ) + { + if (!X509_set_subject_name(ret,dn_subject)) goto err; + } if (!default_op) { @@ -2219,6 +2292,16 @@ again2: EVP_PKEY_copy_parameters(pktmp,pkey); EVP_PKEY_free(pktmp); #endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) + dgst = EVP_ecdsa(); + pktmp = X509_get_pubkey(ret); + if (EVP_PKEY_missing_parameters(pktmp) && + !EVP_PKEY_missing_parameters(pkey)) + EVP_PKEY_copy_parameters(pktmp, pkey); + EVP_PKEY_free(pktmp); +#endif + if (!X509_sign(ret,pkey,dgst)) goto err; @@ -2235,10 +2318,10 @@ again2: /* row[DB_serial] done already */ row[DB_file]=(char *)OPENSSL_malloc(8); - /* row[DB_name] done already */ + row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0); if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || - (row[DB_file] == NULL)) + (row[DB_file] == NULL) || (row[DB_name] == NULL)) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; @@ -2275,6 +2358,8 @@ err: X509_NAME_free(CAname); if (subject != NULL) X509_NAME_free(subject); + if ((dn_subject != NULL) && !email_dn) + X509_NAME_free(dn_subject); if (tmptm != NULL) ASN1_UTCTIME_free(tmptm); if (ok <= 0) @@ -2313,8 +2398,8 @@ 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, TXT_DB *db, - BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, - char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, + BIGNUM *serial, char *subj, 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) { STACK_OF(CONF_VALUE) *sk=NULL; @@ -2405,6 +2490,11 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, continue; } + /* + if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0)) + continue; + */ + j=ASN1_PRINTABLE_type((unsigned char *)buf,-1); if (fix_data(nid, &j) == 0) { @@ -2449,7 +2539,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,startdate,enddate, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, ext_copy); err: @@ -2935,65 +3025,124 @@ int make_revoked(X509_REVOKED *rev, char *str) return ret; } -static X509_NAME *do_subject(char *subject) +/* + * 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) { - X509_NAME *n = NULL; - - int i, nid, ne_num=0; + 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 *ne_name = NULL; - char *ne_value = NULL; + char *sp = subject, *bp = buf; + int i, ne_num = 0; - char *tmp = NULL; - char *p[2]; + X509_NAME *n = NULL; + int nid; - char *str_list[256]; - - p[0] = ",/"; - p[1] = "="; + if (!buf || !ne_types || !ne_values) + { + BIO_printf(bio_err, "malloc error\n"); + goto error; + } - n = X509_NAME_new(); + if (*subject != '/') + { + BIO_printf(bio_err, "Subject does not start with '/'.\n"); + goto error; + } + sp++; /* skip leading / */ - tmp = strtok(subject, p[0]); - while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list))) + while (*sp) + { + /* collect type */ + ne_types[ne_num] = bp; + while (*sp) { - char *token = tmp; - - while (token[0] == ' ') - token++; - str_list[ne_num] = token; - - tmp = strtok(NULL, p[0]); - ne_num++; + 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++) { - ne_name = strtok(str_list[i], p[1]); - ne_value = strtok(NULL, p[1]); - - if ((nid=OBJ_txt2nid(ne_name)) == NID_undef) + if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) { - BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name); + BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); continue; } - if (ne_value == NULL) + if (!*ne_values[i]) { - BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name); + 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, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0)) - { - X509_NAME_free(n); - return NULL; - } + 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) {