X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=apps%2Fca.c;h=7ed60c7a9ac159f04399fc0d4f732e8ed8401f15;hb=2bdcfbd7a3f5abfc0f0421787a001f077e724477;hp=8be557c956a6baeb1df23c3735f5e11df3a235c6;hpb=fb0f53b2e0a4be6a3832f7d10134b01078f5b7dd;p=oweals%2Fopenssl.git diff --git a/apps/ca.c b/apps/ca.c index 8be557c956..7ed60c7a9a 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -64,7 +64,6 @@ #include #include #include -#include "apps.h" #include #include #include @@ -80,7 +79,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,11 +93,13 @@ # else # include # endif -# elif !defined(OPENSSL_SYS_VXWORKS) +# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) # include # endif #endif +#include "apps.h" + #ifndef W_OK # define F_OK 0 # define X_OK 1 @@ -191,7 +196,9 @@ static char *ca_usage[]={ " -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", +#ifndef OPENSSL_NO_ENGINE " -engine e - use engine e, possibly a hardware device.\n", +#endif " -status serial - Shows certificate status given the serial number\n", " -updatedb - Updates db for expired certificates\n", NULL @@ -238,7 +245,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, 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); @@ -329,7 +335,10 @@ int MAIN(int argc, char **argv) #define BSIZE 256 MS_STATIC char buf[3][BSIZE]; char *randfile=NULL; +#ifndef OPENSSL_NO_ENGINE char *engine = NULL; +#endif + char *tofree=NULL; #ifdef EFENCE EF_PROTECT_FREE=1; @@ -532,11 +541,13 @@ EF_ALIGNMENT=0; rev_arg = *(++argv); rev_type = REV_CA_COMPROMISE; } +#ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } +#endif else { bad: @@ -557,25 +568,28 @@ bad: ERR_load_crypto_strings(); - e = setup_engine(bio_err, engine, 0); +#ifndef OPENSSL_NO_ENGINE + e = setup_engine(bio_err, engine, 0); +#endif /*****************************************************************/ + tofree=NULL; 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. */ + const char *s=X509_get_default_cert_area(); + #ifdef OPENSSL_SYS_VMS - strncpy(buf[0],X509_get_default_cert_area(), - sizeof(buf[0])-1-sizeof(CONFIG_FILE)); + tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)); + strcpy(tofree,s); #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],"/"); + tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1); + strcpy(tofree,s); + strcat(tofree,"/"); #endif - strcat(buf[0],CONFIG_FILE); - configfile=buf[0]; + strcat(tofree,CONFIG_FILE); + configfile=tofree; } BIO_printf(bio_err,"Using configuration from %s\n",configfile); @@ -590,6 +604,11 @@ bad: ,errorline,configfile); goto err; } + if(tofree) + { + OPENSSL_free(tofree); + tofree = NULL; + } if (!load_config(bio_err, conf)) goto err; @@ -696,9 +715,9 @@ 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 (key) OPENSSL_cleanse(key,strlen(key)); if (pkey == NULL) { /* load_key() has already printed an appropriate message */ @@ -1013,7 +1032,7 @@ bad: } if (verbose) - BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile); + BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile); /* We can have sections in the ext file */ if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions"))) @@ -1155,9 +1174,14 @@ bad: } if (verbose) { - if ((f=BN_bn2hex(serial)) == NULL) goto err; - BIO_printf(bio_err,"next serial number is %s\n",f); - OPENSSL_free(f); + if (BN_is_zero(serial)) + BIO_printf(bio_err,"next serial number is 00\n"); + else + { + if ((f=BN_bn2hex(serial)) == NULL) goto err; + BIO_printf(bio_err,"next serial number is %s\n",f); + OPENSSL_free(f); + } } if ((attribs=NCONF_get_section(conf,policy)) == NULL) @@ -1277,8 +1301,13 @@ 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'; + if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5) + { + BIO_printf(bio_err,"file name too long\n"); + goto err; + } + + strcpy(buf[0],serialfile); #ifdef OPENSSL_SYS_VMS strcat(buf[0],"-new"); @@ -1288,8 +1317,7 @@ bad: if (!save_serial(buf[0],serial)) goto err; - strncpy(buf[1],dbfile,BSIZE-4); - buf[1][BSIZE-4]='\0'; + strcpy(buf[1],dbfile); #ifdef OPENSSL_SYS_VMS strcat(buf[1],"-new"); @@ -1319,8 +1347,13 @@ bad: j=x->cert_info->serialNumber->length; p=(char *)x->cert_info->serialNumber->data; - strncpy(buf[2],outdir,BSIZE-(j*2)-6); - buf[2][BSIZE-(j*2)-6]='\0'; + if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8)) + { + BIO_printf(bio_err,"certificate file name too long\n"); + goto err; + } + + strcpy(buf[2],outdir); #ifndef OPENSSL_SYS_VMS strcat(buf[2],"/"); @@ -1451,13 +1484,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; @@ -1554,8 +1587,13 @@ bad: if (j <= 0) goto err; X509_free(revcert); - strncpy(buf[0],dbfile,BSIZE-4); - buf[0][BSIZE-4]='\0'; + if(strlen(dbfile) > BSIZE-5) + { + BIO_printf(bio_err,"filename too long\n"); + goto err; + } + + strcpy(buf[0],dbfile); #ifndef OPENSSL_SYS_VMS strcat(buf[0],".new"); #else @@ -1599,16 +1637,19 @@ bad: /*****************************************************************/ ret=0; err: + if(tofree) + OPENSSL_free(tofree); BIO_free_all(Cout); BIO_free_all(Sout); BIO_free_all(out); BIO_free_all(in); - sk_X509_pop_free(cert_sk,X509_free); + if (cert_sk) + sk_X509_pop_free(cert_sk,X509_free); if (ret) ERR_print_errors(bio_err); app_RAND_write_file(randfile, bio_err); - if (free_key) + if (free_key && key) OPENSSL_free(key); BN_free(serial); TXT_DB_free(db); @@ -1618,7 +1659,7 @@ err: NCONF_free(conf); OBJ_cleanup(); apps_shutdown(); - EXIT(ret); + OPENSSL_EXIT(ret); } static void lookup_fail(char *name, char *tag) @@ -1683,7 +1724,7 @@ static BIGNUM *load_serial(char *serialfile) ret=ASN1_INTEGER_to_BN(ai,NULL); if (ret == NULL) { - BIO_printf(bio_err,"error converting number from bin to BIGNUM"); + BIO_printf(bio_err,"error converting number from bin to BIGNUM\n"); goto err; } err: @@ -1874,7 +1915,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) { @@ -2086,9 +2127,11 @@ again2: } } - row[DB_name]=X509_NAME_oneline(dn_subject,NULL,0); - row[DB_serial]=BN_bn2hex(serial); - if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) + if (BN_is_zero(serial)) + row[DB_serial]=BUF_strdup("00"); + else + row[DB_serial]=BN_bn2hex(serial); + if (row[DB_serial] == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; @@ -2150,7 +2193,7 @@ again2: #ifdef X509_V3 /* Make it an X509 v3 certificate. */ - if (!X509_set_version(x509,2)) goto err; + if (!X509_set_version(ret,2)) goto err; #endif if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL) @@ -2301,10 +2344,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; @@ -2571,7 +2614,10 @@ static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value) row[i]=NULL; row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0); bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL); - row[DB_serial]=BN_bn2hex(bn); + if (BN_is_zero(bn)) + row[DB_serial]=BUF_strdup("00"); + else + row[DB_serial]=BN_bn2hex(bn); BN_free(bn); if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) { @@ -3012,13 +3058,13 @@ int make_revoked(X509_REVOKED *rev, char *str) * subject is expected to be in the format /type0=value0/type1=value1/type2=... * where characters may be escaped by \ */ -static X509_NAME *do_subject(char *subject) +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 = malloc (buflen); + 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 = malloc (max_ne * sizeof (char *)); - char **ne_values = malloc (max_ne * sizeof (char *)); + 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; @@ -3029,70 +3075,73 @@ static X509_NAME *do_subject(char *subject) if (!buf || !ne_types || !ne_values) { BIO_printf(bio_err, "malloc error\n"); - goto error0; + goto error; } if (*subject != '/') { BIO_printf(bio_err, "Subject does not start with '/'.\n"); - goto error0; + 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 error0; + 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 error0; - } + 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 error0; + goto error; + } } else if (*sp == '/') - { + { sp++; - *bp++ = '\0'; break; - } + } else *bp++ = *sp++; - } + } *bp++ = '\0'; ne_num++; - } + } if (!(n = X509_NAME_new())) - goto error0; + goto error; for (i = 0; i < ne_num; i++) { @@ -3108,25 +3157,26 @@ static X509_NAME *do_subject(char *subject) continue; } - if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_values[i], -1,-1,0)) - goto error1; + if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0)) + goto error; } - free (ne_values); - free (ne_types); - free (buf); + OPENSSL_free(ne_values); + OPENSSL_free(ne_types); + OPENSSL_free(buf); return n; -error1: +error: X509_NAME_free(n); -error0: - free (ne_values); - free (ne_types); - free (buf); + 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;