X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=apps%2Fapps.c;h=4a8c9263a7cc3e0e59989d7f986a498e01999de7;hb=db186beee4ae2af2ea87f75781d62ea34846e440;hp=9bbf476245c8f783ebbfe723e82f4456a252f57d;hpb=2c7bc88d785b40bd12a5080fc3d2ef9445460079;p=oweals%2Fopenssl.git diff --git a/apps/apps.c b/apps/apps.c index 9bbf476245..4a8c9263a7 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -55,15 +55,66 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #include #include #include #include #include -#define NON_MAIN -#include "apps.h" -#undef NON_MAIN +#include #include #include #include @@ -71,13 +122,22 @@ #include #include #include +#include #ifdef OPENSSL_SYS_WINDOWS #define strcasecmp _stricmp #else -#include +# ifdef NO_STRINGS_H + int strcasecmp(); +# else +# include +# endif /* NO_STRINGS_H */ #endif +#define NON_MAIN +#include "apps.h" +#undef NON_MAIN + #ifdef OPENSSL_SYS_WINDOWS # include "bss_file.c" #endif @@ -93,6 +153,13 @@ static UI_METHOD *ui_method = NULL; static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 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 *err, BIO *key, const char *file, + const char *key_descrip, int format); +#endif + int app_init(long mesgwin); #ifdef undef /* never finished - probably never will be :-) */ int args_from_file(char *file, int *argc, char **argv[]) @@ -249,9 +316,16 @@ void program_name(char *in, char *out, int size) q=strrchr(p,'.'); if (q == NULL) - q = in+size; - strncpy(out,p,q-p); - out[q-p]='\0'; + q = p + strlen(p); + strncpy(out,p,size-1); + if (q-p >= size) + { + out[size-1]='\0'; + } + else + { + out[q-p]='\0'; + } } #else void program_name(char *in, char *out, int size) @@ -263,8 +337,7 @@ void program_name(char *in, char *out, int size) p++; else p=in; - strncpy(out,p,size-1); - out[size-1]='\0'; + BUF_strlcpy(out,p,size); } #endif #endif @@ -272,19 +345,57 @@ void program_name(char *in, char *out, int size) #ifdef OPENSSL_SYS_WIN32 int WIN32_rename(char *from, char *to) { -#ifdef OPENSSL_SYS_WINNT - int ret; -/* Note: MoveFileEx() doesn't work under Win95, Win98 */ - - ret=MoveFileEx(from,to,MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED); - return(ret?0:-1); +#ifndef OPENSSL_SYS_WINCE + /* Windows rename gives an error if 'to' exists, so delete it + * first and ignore file not found errror + */ + if((remove(to) != 0) && (errno != ENOENT)) + return -1; +#undef rename + return rename(from, to); #else - unlink(to); - return MoveFile(from, to); + /* convert strings to UNICODE */ + { + BOOL result = FALSE; + WCHAR* wfrom; + WCHAR* wto; + int i; + wfrom = malloc((strlen(from)+1)*2); + wto = malloc((strlen(to)+1)*2); + if (wfrom != NULL && wto != NULL) + { + for (i=0; i<(int)strlen(from)+1; i++) + wfrom[i] = (short)from[i]; + for (i=0; i<(int)strlen(to)+1; i++) + wto[i] = (short)to[i]; + result = MoveFile(wfrom, wto); + } + if (wfrom != NULL) + free(wfrom); + if (wto != NULL) + free(wto); + return result; + } #endif } #endif +#ifdef OPENSSL_SYS_VMS +int VMS_strcasecmp(const char *str1, const char *str2) + { + while (*str1 && *str2) + { + int res = toupper(*str1) - toupper(*str2); + if (res) return res < 0 ? -1 : 1; + } + if (*str1) + return 1; + if (*str2) + return -1; + return 0; + } +#endif + int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) { int num,len,i; @@ -360,16 +471,20 @@ int app_init(long mesgwin) int dump_cert_text (BIO *out, X509 *x) { - char buf[256]; - X509_NAME_oneline(X509_get_subject_name(x),buf,256); + char *p; + + p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0); BIO_puts(out,"subject="); - BIO_puts(out,buf); + BIO_puts(out,p); + OPENSSL_free(p); - X509_NAME_oneline(X509_get_issuer_name(x),buf,256); - BIO_puts(out,"\nissuer= "); - BIO_puts(out,buf); + p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0); + BIO_puts(out,"\nissuer="); + BIO_puts(out,p); BIO_puts(out,"\n"); - return 0; + OPENSSL_free(p); + + return 0; } static int ui_open(UI *ui) @@ -390,7 +505,7 @@ static int ui_read(UI *ui, UI_STRING *uis) ((PW_CB_DATA *)UI_get0_user_data(ui))->password; if (password[0] != '\0') { - UI_set_result(uis, password); + UI_set_result(ui, uis, password); return 1; } } @@ -425,7 +540,7 @@ static int ui_close(UI *ui) { return UI_method_get_closer(UI_OpenSSL())(ui); } -int setup_ui_method() +int setup_ui_method(void) { ui_method = UI_create_method("OpenSSL application user interface"); UI_method_set_opener(ui_method, ui_open); @@ -434,7 +549,7 @@ int setup_ui_method() UI_method_set_closer(ui_method, ui_close); return 0; } -void destroy_ui_method() +void destroy_ui_method(void) { if(ui_method) { @@ -459,11 +574,18 @@ int password_callback(char *buf, int bufsiz, int verify, prompt_info = cb_data->prompt_info; } + if (password) + { + res = strlen(password); + if (res > bufsiz) + res = bufsiz; + memcpy(buf, password, res); + return res; + } + ui = UI_new_method(ui_method); if (ui) { - char errstring[80]; - int errstring_added = 0; int ok = 0; char *buff = NULL; int ui_flags = 0; @@ -473,58 +595,47 @@ int password_callback(char *buf, int bufsiz, int verify, cb_data->prompt_info); ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; + UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); if (ok >= 0) - ok = UI_add_input_string(ui,prompt,ui_flags,buf,0,BUFSIZ-1); + ok = UI_add_input_string(ui,prompt,ui_flags,buf, + PW_MIN_LENGTH,BUFSIZ-1); if (ok >= 0 && verify) { buff = (char *)OPENSSL_malloc(bufsiz); - ok = UI_add_verify_string(ui,prompt,ui_flags,buff,0,BUFSIZ-1, - buf); + ok = UI_add_verify_string(ui,prompt,ui_flags,buff, + PW_MIN_LENGTH,BUFSIZ-1, buf); } if (ok >= 0) - for(;;) + do { - res = 0; - ok=UI_process(ui); - if (ok < 0) - break; - res=strlen(buf); - if (res < PW_MIN_LENGTH) - { - if (errstring_added == 0) - { - BIO_snprintf(errstring, - sizeof(errstring), -"phrase is too short, needs to be at least %d chars\n", PW_MIN_LENGTH); - UI_add_error_string(ui, - errstring); - } - errstring_added = 1; - } - else - break; + ok = UI_process(ui); } + while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + if (buff) { - memset(buf,0,(unsigned int)bufsiz); + OPENSSL_cleanse(buff,(unsigned int)bufsiz); OPENSSL_free(buff); } + if (ok >= 0) + res = strlen(buf); if (ok == -1) { BIO_printf(bio_err, "User interface error\n"); ERR_print_errors(bio_err); - memset(buf,0,(unsigned int)bufsiz); + OPENSSL_cleanse(buf,(unsigned int)bufsiz); res = 0; } if (ok == -2) { BIO_printf(bio_err,"aborted!\n"); - memset(buf,0,(unsigned int)bufsiz); + OPENSSL_cleanse(buf,(unsigned int)bufsiz); res = 0; } UI_free(ui); + OPENSSL_free(prompt); } return res; } @@ -604,18 +715,18 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) return BUF_strdup(tpass); } -int add_oid_section(BIO *err, LHASH *conf) +int add_oid_section(BIO *err, CONF *conf) { char *p; STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *cnf; int i; - if(!(p=CONF_get_string(conf,NULL,"oid_section"))) + if(!(p=NCONF_get_string(conf,NULL,"oid_section"))) { ERR_clear_error(); return 1; } - if(!(sktmp = CONF_get_section(conf, p))) { + if(!(sktmp = NCONF_get_section(conf, p))) { BIO_printf(err, "problem loading oid section %s\n", p); return 0; } @@ -733,7 +844,7 @@ end: return(x); } -EVP_PKEY *load_key(BIO *err, const char *file, int format, +EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip) { BIO *key=NULL; @@ -743,7 +854,7 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, cb_data.password = pass; cb_data.prompt_info = file; - if (file == NULL) + if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { BIO_printf(err,"no keyfile specified\n"); goto end; @@ -763,12 +874,19 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, ERR_print_errors(err); goto end; } - if (BIO_read_filename(key,file) <= 0) + if (file == NULL && maybe_stdin) { - BIO_printf(err, "Error opening %s %s\n", key_descrip, file); - ERR_print_errors(err); - goto end; + setvbuf(stdin, NULL, _IONBF, 0); + BIO_set_fp(key,stdin,BIO_NOCLOSE); } + else + if (BIO_read_filename(key,file) <= 0) + { + BIO_printf(err, "Error opening %s %s\n", + key_descrip, file); + ERR_print_errors(err); + goto end; + } if (format == FORMAT_ASN1) { pkey=d2i_PrivateKey_bio(key, NULL); @@ -778,6 +896,10 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, pkey=PEM_read_bio_PrivateKey(key,NULL, (pem_password_cb *)password_callback, &cb_data); } +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) + else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) + pkey = load_netscape_key(err, key, file, key_descrip, format); +#endif else if (format == FORMAT_PKCS12) { PKCS12 *p12 = d2i_PKCS12_bio(key, NULL); @@ -798,7 +920,7 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, return(pkey); } -EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, +EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip) { BIO *key=NULL; @@ -808,7 +930,7 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, cb_data.password = pass; cb_data.prompt_info = file; - if (file == NULL) + if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { BIO_printf(err,"no keyfile specified\n"); goto end; @@ -828,11 +950,18 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, ERR_print_errors(err); goto end; } - if (BIO_read_filename(key,file) <= 0) + if (file == NULL && maybe_stdin) { - BIO_printf(err, "Error opening %s %s\n", key_descrip, file); - ERR_print_errors(err); - goto end; + setvbuf(stdin, NULL, _IONBF, 0); + BIO_set_fp(key,stdin,BIO_NOCLOSE); + } + else + if (BIO_read_filename(key,file) <= 0) + { + BIO_printf(err, "Error opening %s %s\n", + key_descrip, file); + ERR_print_errors(err); + goto end; } if (format == FORMAT_ASN1) { @@ -843,6 +972,10 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, pkey=PEM_read_bio_PUBKEY(key,NULL, (pem_password_cb *)password_callback, &cb_data); } +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) + else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) + pkey = load_netscape_key(err, key, file, key_descrip, format); +#endif else { BIO_printf(err,"bad input format specified for key file\n"); @@ -855,6 +988,52 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, return(pkey); } +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) +static EVP_PKEY * +load_netscape_key(BIO *err, 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(err, "Error reading %s %s", + key_descrip, file); + goto error; + } + } + p=(unsigned char *)buf->data; + rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL, + (format == FORMAT_IISSGC ? 1 : 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 */ + STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip) { @@ -955,6 +1134,7 @@ int set_cert_ex(unsigned long *flags, const char *arg) { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, { "no_aux", X509_FLAG_NO_AUX, 0}, + { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, @@ -1098,18 +1278,20 @@ static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_T void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags) { - char buf[256]; + char *buf; char mline = 0; int indent = 0; + if(title) BIO_puts(out, title); if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mline = 1; indent = 4; } if(lflags == XN_FLAG_COMPAT) { - X509_NAME_oneline(nm,buf,256); - BIO_puts(out,buf); + buf = X509_NAME_oneline(nm, 0, 0); + BIO_puts(out, buf); BIO_puts(out, "\n"); + OPENSSL_free(buf); } else { if(mline) BIO_puts(out, "\n"); X509_NAME_print_ex(out, nm, indent, lflags); @@ -1147,15 +1329,39 @@ X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) return NULL; } +/* Try to load an engine in a shareable library */ +static ENGINE *try_load_engine(BIO *err, const char *engine, int debug) + { + ENGINE *e = ENGINE_by_id("dynamic"); + if (e) + { + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) + || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) + { + ENGINE_free(e); + e = NULL; + } + } + return e; + } + ENGINE *setup_engine(BIO *err, const char *engine, int debug) { ENGINE *e = NULL; if (engine) { - if((e = ENGINE_by_id(engine)) == NULL) + if(strcmp(engine, "auto") == 0) + { + BIO_printf(err,"enabling auto ENGINE support\n"); + ENGINE_register_all_complete(); + return NULL; + } + if((e = ENGINE_by_id(engine)) == NULL + && (e = try_load_engine(err, engine, debug)) == NULL) { BIO_printf(err,"invalid engine \"%s\"\n", engine); + ERR_print_errors(err); return NULL; } if (debug) @@ -1167,11 +1373,48 @@ ENGINE *setup_engine(BIO *err, const char *engine, int debug) if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { BIO_printf(err,"can't use that engine\n"); + ERR_print_errors(err); + ENGINE_free(e); return NULL; } - BIO_printf(err,"engine \"%s\" set.\n", engine); + + BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e)); + /* Free our "structural" reference. */ ENGINE_free(e); } return e; } + +int load_config(BIO *err, CONF *cnf) + { + if (!cnf) + cnf = config; + if (!cnf) + return 1; + + OPENSSL_load_builtin_modules(); + + if (CONF_modules_load(cnf, NULL, 0) <= 0) + { + BIO_printf(err, "Error configuring OpenSSL\n"); + ERR_print_errors(err); + return 0; + } + return 1; + } + +char *make_config_name() + { + const char *t=X509_get_default_cert_area(); + char *p; + + p=OPENSSL_malloc(strlen(t)+strlen(OPENSSL_CONF)+2); + strcpy(p,t); +#ifndef OPENSSL_SYS_VMS + strcat(p,"/"); +#endif + strcat(p,OPENSSL_CONF); + + return p; + }