X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=apps%2Fapps.c;h=c6b70d63a870b5da7b902df5a01be5edc4926e47;hb=012c5408507b0c85e0af14efbda51d906d620508;hp=1c182bafb60b05d27db69afa9ac733bae1e60765;hpb=86885c289580066792415218754bd935b449f170;p=oweals%2Fopenssl.git diff --git a/apps/apps.c b/apps/apps.c index 1c182bafb6..c6b70d63a8 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -118,13 +118,15 @@ #include #include #include -#if !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_WINCE) && !defined(NETWARE_CLIB) -# include +#ifndef NO_SYS_TYPES_H +# include +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include +# include #endif -#include #include #include -#include #include #include #include @@ -164,12 +166,6 @@ static int set_table_opts(unsigned long *flags, const char *arg, static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL * in_tbl); -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) -/* Looks like this stuff is worth moving into separate function */ -static EVP_PKEY *load_netscape_key(BIO *key, const char *file, - const char *key_descrip, int format); -#endif - int app_init(long mesgwin); int chopup_args(ARGS *arg, char *buf) @@ -228,11 +224,17 @@ int app_init(long mesgwin) } #endif -int ctx_set_verify_locations(SSL_CTX *ctx, - const char *CAfile, const char *CApath) +int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath, int noCAfile, int noCApath) { - if (CAfile == NULL && CApath == NULL) - return SSL_CTX_set_default_verify_paths(ctx); + if (CAfile == NULL && CApath == NULL) { + if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0) + return 0; + if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0) + return 0; + + return 1; + } return SSL_CTX_load_verify_locations(ctx, CAfile, CApath); } @@ -471,7 +473,7 @@ static char *app_get_pass(char *arg, int keepbio) pwdbio = BIO_push(btmp, pwdbio); #endif } else if (strcmp(arg, "stdin") == 0) { - pwdbio = dup_bio_in(); + pwdbio = dup_bio_in(FORMAT_TEXT); if (!pwdbio) { BIO_printf(bio_err, "Can't open BIO for stdin\n"); return NULL; @@ -496,17 +498,84 @@ static char *app_get_pass(char *arg, int keepbio) return BUF_strdup(tpass); } +static CONF *app_load_config_(BIO *in, const char *filename) +{ + long errorline = -1; + CONF *conf; + int i; + + conf = NCONF_new(NULL); + i = NCONF_load_bio(conf, in, &errorline); + if (i > 0) + return conf; + + if (errorline <= 0) + BIO_printf(bio_err, "%s: Can't load config file \"%s\"\n", + opt_getprog(), filename); + else + BIO_printf(bio_err, "%s: Error on line %ld of config file \"%s\"\n", + opt_getprog(), errorline, filename); + NCONF_free(conf); + return NULL; +} +CONF *app_load_config(const char *filename) +{ + BIO *in; + CONF *conf; + + in = bio_open_default(filename, 'r', FORMAT_TEXT); + if (in == NULL) + return NULL; + + conf = app_load_config_(in, filename); + BIO_free(in); + return conf; +} +CONF *app_load_config_quiet(const char *filename) +{ + BIO *in; + CONF *conf; + + in = bio_open_default_quiet(filename, 'r', FORMAT_TEXT); + if (in == NULL) + return NULL; + + conf = app_load_config_(in, filename); + BIO_free(in); + return conf; +} + +int app_load_modules(const CONF *config) +{ + CONF *to_free = NULL; + + if (config == NULL) + config = to_free = app_load_config_quiet(default_config_file); + if (config == NULL) + return 1; + + if (CONF_modules_load(config, NULL, 0) <= 0) { + BIO_printf(bio_err, "Error configuring OpenSSL modules\n"); + ERR_print_errors(bio_err); + NCONF_free(to_free); + return 0; + } + NCONF_free(to_free); + return 1; +} + int add_oid_section(CONF *conf) { char *p; STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *cnf; int i; - if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) { + + if ((p = NCONF_get_string(conf, NULL, "oid_section")) == NULL) { ERR_clear_error(); return 1; } - if (!(sktmp = NCONF_get_section(conf, p))) { + if ((sktmp = NCONF_get_section(conf, p)) == NULL) { BIO_printf(bio_err, "problem loading oid section %s\n", p); return 0; } @@ -577,7 +646,7 @@ int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl) if (!bio || !BIO_set_conn_port(bio, port)) goto err; rctx = OCSP_REQ_CTX_new(bio, 1024); - if (!rctx) + if (rctx == NULL) goto err; if (!OCSP_REQ_CTX_http(rctx, "GET", path)) goto err; @@ -621,30 +690,15 @@ X509 *load_cert(const char *file, int format, if (file == NULL) { unbuffer(stdin); - cert = dup_bio_in(); + cert = dup_bio_in(format); } else - cert = bio_open_default(file, RB(format)); + cert = bio_open_default(file, 'r', format); if (cert == NULL) goto end; if (format == FORMAT_ASN1) x = d2i_X509_bio(cert, NULL); - else if (format == FORMAT_NETSCAPE) { - NETSCAPE_X509 *nx; - nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509), cert, NULL); - if (nx == NULL) - goto end; - - if ((strncmp(NETSCAPE_CERT_HDR, (char *)nx->header->data, - nx->header->length) != 0)) { - NETSCAPE_X509_free(nx); - BIO_printf(bio_err, "Error reading header on certificate\n"); - goto end; - } - x = nx->cert; - nx->cert = NULL; - NETSCAPE_X509_free(nx); - } else if (format == FORMAT_PEM) + else if (format == FORMAT_PEM) x = PEM_read_bio_X509_AUX(cert, NULL, (pem_password_cb *)password_callback, NULL); else if (format == FORMAT_PKCS12) { @@ -673,7 +727,7 @@ X509_CRL *load_crl(const char *infile, int format) return x; } - in = bio_open_default(infile, RB(format)); + in = bio_open_default(infile, 'r', format); if (in == NULL) goto end; if (format == FORMAT_ASN1) @@ -725,9 +779,9 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, #endif if (file == NULL && maybe_stdin) { unbuffer(stdin); - key = dup_bio_in(); + key = dup_bio_in(format); } else - key = bio_open_default(file, RB(format)); + key = bio_open_default(file, 'r', format); if (key == NULL) goto end; if (format == FORMAT_ASN1) { @@ -737,10 +791,6 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, (pem_password_cb *)password_callback, &cb_data); } -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) - else if (format == FORMAT_NETSCAPE) - pkey = load_netscape_key(key, file, key_descrip, format); -#endif else if (format == FORMAT_PKCS12) { if (!load_pkcs12(key, key_descrip, (pem_password_cb *)password_callback, &cb_data, @@ -767,13 +817,6 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, return (pkey); } -static const char *key_file_format(int format) -{ - if (format == FORMAT_PEM || format == FORMAT_PEMRSA) - return "r"; - return "rb"; -} - EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip) { @@ -799,9 +842,9 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, #endif if (file == NULL && maybe_stdin) { unbuffer(stdin); - key = dup_bio_in(); + key = dup_bio_in(format); } else - key = bio_open_default(file, key_file_format(format)); + key = bio_open_default(file, 'r', format); if (key == NULL) goto end; if (format == FORMAT_ASN1) { @@ -813,7 +856,7 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, rsa = d2i_RSAPublicKey_bio(key, NULL); if (rsa) { pkey = EVP_PKEY_new(); - if (pkey) + if (pkey != NULL) EVP_PKEY_set1_RSA(pkey, rsa); RSA_free(rsa); } else @@ -823,9 +866,9 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, rsa = PEM_read_bio_RSAPublicKey(key, NULL, (pem_password_cb *)password_callback, &cb_data); - if (rsa) { + if (rsa != NULL) { pkey = EVP_PKEY_new(); - if (pkey) + if (pkey != NULL) EVP_PKEY_set1_RSA(pkey, rsa); RSA_free(rsa); } else @@ -837,10 +880,6 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, (pem_password_cb *)password_callback, &cb_data); } -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) - else if (format == FORMAT_NETSCAPE) - pkey = load_netscape_key(key, file, key_descrip, format); -#endif #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) else if (format == FORMAT_MSBLOB) pkey = b2i_PublicKey_bio(key); @@ -852,47 +891,6 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, return (pkey); } -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) -static EVP_PKEY *load_netscape_key(BIO *key, const char *file, - const char *key_descrip, int format) -{ - EVP_PKEY *pkey; - BUF_MEM *buf; - RSA *rsa; - const unsigned char *p; - int size, i; - - buf = BUF_MEM_new(); - pkey = EVP_PKEY_new(); - size = 0; - if (buf == NULL || pkey == NULL) - goto error; - for (;;) { - if (!BUF_MEM_grow_clean(buf, size + 1024 * 10)) - goto error; - i = BIO_read(key, &(buf->data[size]), 1024 * 10); - size += i; - if (i == 0) - break; - if (i < 0) { - BIO_printf(bio_err, "Error reading %s %s", key_descrip, file); - goto error; - } - } - p = (unsigned char *)buf->data; - rsa = d2i_RSA_NET(NULL, &p, (long)size, NULL, 0); - if (rsa == NULL) - goto error; - BUF_MEM_free(buf); - EVP_PKEY_set1_RSA(pkey, rsa); - return pkey; - error: - BUF_MEM_free(buf); - EVP_PKEY_free(pkey); - return NULL; -} -#endif /* ndef OPENSSL_NO_RC4 */ - static int load_certs_crls(const char *file, int format, const char *pass, ENGINE *e, const char *desc, STACK_OF(X509) **pcerts, @@ -913,7 +911,7 @@ static int load_certs_crls(const char *file, int format, return 0; } - bio = bio_open_default(file, "r"); + bio = bio_open_default(file, 'r', FORMAT_PEM); if (bio == NULL) return 0; @@ -1079,7 +1077,11 @@ int set_name_ex(unsigned long *flags, const char *arg) {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, {NULL, 0, 0} }; - return set_multi_opts(flags, arg, ex_tbl); + if (set_multi_opts(flags, arg, ex_tbl) == 0) + return 0; + if ((*flags & XN_FLAG_SEP_MASK) == 0) + *flags |= XN_FLAG_SEP_CPLUS_SPC; + return 1; } int set_ext_copy(int *copy_type, const char *arg) @@ -1245,34 +1247,39 @@ void print_array(BIO *out, const char* title, int len, const unsigned char* d) BIO_printf(out, "\n};\n"); } -X509_STORE *setup_verify(char *CAfile, char *CApath) +X509_STORE *setup_verify(char *CAfile, char *CApath, int noCAfile, int noCApath) { X509_STORE *store = X509_STORE_new(); X509_LOOKUP *lookup; - if (!store) - goto end; - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - if (lookup == NULL) + if (store == NULL) goto end; - if (CAfile) { - if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { - BIO_printf(bio_err, "Error loading file %s\n", CAfile); + + if(CAfile != NULL || !noCAfile) { + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); + if (lookup == NULL) goto end; - } - } else - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + if (CAfile) { + if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { + BIO_printf(bio_err, "Error loading file %s\n", CAfile); + goto end; + } + } else + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + } - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - goto end; - if (CApath) { - if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { - BIO_printf(bio_err, "Error loading directory %s\n", CApath); + if(CApath != NULL || !noCApath) { + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) goto end; - } - } else - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + if (CApath) { + if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { + BIO_printf(bio_err, "Error loading directory %s\n", CApath); + goto end; + } + } else + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + } ERR_clear_error(); return store; @@ -1534,7 +1541,7 @@ int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) else btmp = BN_new(); - if (!btmp) + if (btmp == NULL) return 0; if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) @@ -1558,8 +1565,7 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) TXT_DB *tmpdb = NULL; BIO *in; CONF *dbattr_conf = NULL; - char buf[1][BSIZE]; - long errorline = -1; + char buf[BSIZE]; in = BIO_new_file(dbfile, "r"); if (in == NULL) { @@ -1570,22 +1576,11 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) goto err; #ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); + BIO_snprintf(buf, sizeof buf, "%s.attr", dbfile); #else - BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile); + BIO_snprintf(buf, sizeof buf, "%s-attr", dbfile); #endif - dbattr_conf = NCONF_new(NULL); - if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) { - if (errorline > 0) { - BIO_printf(bio_err, - "error on line %ld of db attribute file '%s'\n", - errorline, buf[0]); - goto err; - } else { - NCONF_free(dbattr_conf); - dbattr_conf = NULL; - } - } + dbattr_conf = app_load_config(buf); retdb = app_malloc(sizeof(*retdb), "new DB"); retdb->db = tmpdb; @@ -1906,7 +1901,7 @@ int bio_to_mem(unsigned char **out, int maxlen, BIO *in) int len, ret; unsigned char tbuf[1024]; mem = BIO_new(BIO_s_mem()); - if (!mem) + if (mem == NULL) return -1; for (;;) { if ((maxlen != -1) && maxlen < 1024) @@ -2201,7 +2196,6 @@ void jpake_server_auth(BIO *out, BIO *conn, const char *secret) #endif -#ifndef OPENSSL_NO_TLSEXT /*- * next_protos_parse parses a comma separated list of strings into a string * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. @@ -2237,7 +2231,6 @@ unsigned char *next_protos_parse(unsigned short *outlen, const char *in) *outlen = len + 1; return out; } -#endif /* ndef OPENSSL_NO_TLSEXT */ void print_cert_checks(BIO *bio, X509 *x, const char *checkhost, @@ -2732,3 +2725,176 @@ int raw_write_stdout(const void *buf, int siz) return write(fileno(stdout), buf, siz); } #endif + +/* + * Centralized handling if input and output files with format specification + * The format is meant to show what the input and output is supposed to be, + * and is therefore a show of intent more than anything else. However, it + * does impact behavior on some platform, such as differentiating between + * text and binary input/output on non-Unix platforms + */ +static int istext(int format) +{ + return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT; +} + +BIO *dup_bio_in(int format) +{ + return BIO_new_fp(stdin, + BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); +} + +BIO *dup_bio_out(int format) +{ + BIO *b = BIO_new_fp(stdout, + BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); +#ifdef OPENSSL_SYS_VMS + if (istext(format)) + b = BIO_push(BIO_new(BIO_f_linebuffer()), b); +#endif + return b; +} + +void unbuffer(FILE *fp) +{ + setbuf(fp, NULL); +} + +static const char *modestr(char mode, int format) +{ + OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w'); + + switch (mode) { + case 'a': + return istext(format) ? "a" : "ab"; + case 'r': + return istext(format) ? "r" : "rb"; + case 'w': + return istext(format) ? "w" : "wb"; + } + /* The assert above should make sure we never reach this point */ + return NULL; +} + +static const char *modeverb(char mode) +{ + switch (mode) { + case 'a': + return "appending"; + case 'r': + return "reading"; + case 'w': + return "writing"; + } + return "(doing something)"; +} + +/* + * Open a file for writing, owner-read-only. + */ +BIO *bio_open_owner(const char *filename, int format, int private) +{ + FILE *fp = NULL; + BIO *b = NULL; + int fd = -1, bflags, mode, binmode; + + if (!private || filename == NULL || strcmp(filename, "-") == 0) + return bio_open_default(filename, 'w', format); + + mode = O_WRONLY; +#ifdef O_CREAT + mode |= O_CREAT; +#endif +#ifdef O_TRUNC + mode |= O_TRUNC; +#endif + binmode = istext(format); + if (binmode) { +#ifdef O_BINARY + mode |= O_BINARY; +#elif defined(_O_BINARY) + mode |= _O_BINARY; +#endif + } + + fd = open(filename, mode, 0600); + if (fd < 0) + goto err; + fp = fdopen(fd, modestr('w', format)); + if (fp == NULL) + goto err; + bflags = BIO_CLOSE; + if (!binmode) + bflags |= BIO_FP_TEXT; + b = BIO_new_fp(fp, bflags); + if (b) + return b; + + err: + BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n", + opt_getprog(), filename, strerror(errno)); + ERR_print_errors(bio_err); + /* If we have fp, then fdopen took over fd, so don't close both. */ + if (fp) + fclose(fp); + else if (fd >= 0) + close(fd); + return NULL; +} + +static BIO *bio_open_default_(const char *filename, char mode, int format, + int quiet) +{ + BIO *ret; + + if (filename == NULL || strcmp(filename, "-") == 0) { + ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format); + if (quiet) { + ERR_clear_error(); + return ret; + } + if (ret != NULL) + return ret; + BIO_printf(bio_err, + "Can't open %s, %s\n", + mode == 'r' ? "stdin" : "stdout", strerror(errno)); + } else { + ret = BIO_new_file(filename, modestr(mode, format)); + if (quiet) { + ERR_clear_error(); + return ret; + } + if (ret != NULL) + return ret; + BIO_printf(bio_err, + "Can't open %s for %s, %s\n", + filename, modeverb(mode), strerror(errno)); + } + ERR_print_errors(bio_err); + return NULL; +} + +BIO *bio_open_default(const char *filename, char mode, int format) +{ + return bio_open_default_(filename, mode, format, 0); +} + +BIO *bio_open_default_quiet(const char *filename, char mode, int format) +{ + return bio_open_default_(filename, mode, format, 1); +} + +void wait_for_async(SSL *s) +{ + int width, fd; + fd_set asyncfds; + + fd = SSL_get_async_wait_fd(s); + if (fd < 0) + return; + + width = fd + 1; + FD_ZERO(&asyncfds); + openssl_fdset(fd, &asyncfds); + select(width, (void *)&asyncfds, NULL, NULL, NULL); +}