X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fapps.c;h=09d9df2817a7e669f7b2a92279b9a998b5fcb79b;hp=ee5edaa7b8fe95b0a79497594f37f4268bd58af2;hb=636b6b450dcc0c694780ea34ed2f5d4a39d5d9b5;hpb=f5301388766a1e30a377cb131cfa5fba782bda0b diff --git a/apps/apps.c b/apps/apps.c index ee5edaa7b8..09d9df2817 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -109,12 +109,22 @@ * */ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 2 /* On VMS, you need to define this to get + the declaration of fileno(). The value + 2 is to make sure no function defined + in POSIX-2 is left undefined. */ +#endif #include #include #include +#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB) +#include +#endif #include #include #include +#include #include #include #include @@ -129,6 +139,9 @@ #include #endif #include +#ifndef OPENSSL_NO_JPAKE +#include +#endif #define NON_MAIN #include "apps.h" @@ -248,13 +261,6 @@ int str2fmt(char *s) return(FORMAT_ASN1); else if ((*s == 'T') || (*s == 't')) return(FORMAT_TEXT); - else if ((*s == 'P') || (*s == 'p')) - { - if (s[1] == 'V' || s[1] == 'v') - return FORMAT_PVK; - else - return(FORMAT_PEM); - } else if ((*s == 'N') || (*s == 'n')) return(FORMAT_NETSCAPE); else if ((*s == 'S') || (*s == 's')) @@ -267,6 +273,13 @@ int str2fmt(char *s) return(FORMAT_PKCS12); else if ((*s == 'E') || (*s == 'e')) return(FORMAT_ENGINE); + else if ((*s == 'P') || (*s == 'p')) + { + if (s[1] == 'V' || s[1] == 'v') + return FORMAT_PVK; + else + return(FORMAT_PEM); + } else return(FORMAT_UNDEF); } @@ -910,11 +923,13 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, &pkey, NULL, NULL)) goto end; } +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) else if (format == FORMAT_MSBLOB) pkey = b2i_PrivateKey_bio(key); else if (format == FORMAT_PVK) pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, &cb_data); +#endif else { BIO_printf(err,"bad input format specified for key file\n"); @@ -978,6 +993,7 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, { pkey=d2i_PUBKEY_bio(key, NULL); } +#ifndef OPENSSL_NO_RSA else if (format == FORMAT_ASN1RSA) { RSA *rsa; @@ -1007,7 +1023,7 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, else pkey = NULL; } - +#endif else if (format == FORMAT_PEM) { pkey=PEM_read_bio_PUBKEY(key,NULL, @@ -1017,8 +1033,10 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) pkey = load_netscape_key(err, 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); +#endif else { BIO_printf(err,"bad input format specified for key file\n"); @@ -1433,6 +1451,10 @@ ENGINE *setup_engine(BIO *err, const char *engine, int debug) int load_config(BIO *err, CONF *cnf) { + static int load_config_called = 0; + if (load_config_called) + return 1; + load_config_called = 1; if (!cnf) cnf = config; if (!cnf) @@ -1466,7 +1488,7 @@ char *make_config_name() return p; } -static unsigned long index_serial_hash(const char **a) +static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) { const char *n; @@ -1475,7 +1497,7 @@ static unsigned long index_serial_hash(const char **a) return(lh_strhash(n)); } -static int index_serial_cmp(const char **a, const char **b) +static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) { const char *aa,*bb; @@ -1487,17 +1509,16 @@ static int index_serial_cmp(const char **a, const char **b) static int index_name_qual(char **a) { return(a[0][0] == 'V'); } -static unsigned long index_name_hash(const char **a) +static unsigned long index_name_hash(const OPENSSL_CSTRING *a) { return(lh_strhash(a[DB_name])); } -int index_name_cmp(const char **a, const char **b) - { return(strcmp(a[DB_name], - b[DB_name])); } +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) + { return(strcmp(a[DB_name], b[DB_name])); } -static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **) -static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **) -static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **) -static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **) +static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) #undef BSIZE #define BSIZE 256 @@ -1730,10 +1751,7 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) goto err; } if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL) - { - if (tmpdb != NULL) TXT_DB_free(tmpdb); goto err; - } #ifndef OPENSSL_SYS_VMS BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); @@ -1794,8 +1812,8 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) int index_index(CA_DB *db) { if (!TXT_DB_create_index(db->db, DB_serial, NULL, - LHASH_HASH_FN(index_serial_hash), - LHASH_COMP_FN(index_serial_cmp))) + LHASH_HASH_FN(index_serial), + LHASH_COMP_FN(index_serial))) { BIO_printf(bio_err, "error creating serial number index:(%ld,%ld,%ld)\n", @@ -1805,8 +1823,8 @@ int index_index(CA_DB *db) if (db->attributes.unique_subject && !TXT_DB_create_index(db->db, DB_name, index_name_qual, - LHASH_HASH_FN(index_name_hash), - LHASH_COMP_FN(index_name_cmp))) + LHASH_HASH_FN(index_name), + LHASH_COMP_FN(index_name))) { BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n", db->db->error,db->db->arg1,db->db->arg2); @@ -2022,7 +2040,7 @@ int parse_yesno(const char *str, int def) case 'y': /* yes */ case 'Y': /* YES */ case '1': /* 1 */ - ret = 0; + ret = 1; break; default: ret = def; @@ -2174,7 +2192,7 @@ int args_verify(char ***pargs, int *pargc, ASN1_OBJECT *otmp = NULL; unsigned long flags = 0; int i; - int purpose = 0; + int purpose = 0, depth = -1; char **oldargs = *pargs; char *arg = **pargs, *argn = (*pargs)[1]; if (!strcmp(arg, "-policy")) @@ -2214,6 +2232,21 @@ int args_verify(char ***pargs, int *pargc, } (*pargs)++; } + else if (strcmp(arg,"-verify_depth") == 0) + { + if (!argn) + *badarg = 1; + else + { + depth = atoi(argn); + if(depth < 0) + { + BIO_printf(err, "invalid depth\n"); + *badarg = 1; + } + } + (*pargs)++; + } else if (!strcmp(arg, "-ignore_critical")) flags |= X509_V_FLAG_IGNORE_CRITICAL; else if (!strcmp(arg, "-issuer_checks")) @@ -2226,10 +2259,20 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_POLICY_CHECK; else if (!strcmp(arg, "-explicit_policy")) flags |= X509_V_FLAG_EXPLICIT_POLICY; + else if (!strcmp(arg, "-inhibit_any")) + flags |= X509_V_FLAG_INHIBIT_ANY; + else if (!strcmp(arg, "-inhibit_map")) + flags |= X509_V_FLAG_INHIBIT_MAP; else if (!strcmp(arg, "-x509_strict")) flags |= X509_V_FLAG_X509_STRICT; + else if (!strcmp(arg, "-extended_crl")) + flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; + else if (!strcmp(arg, "-use_deltas")) + flags |= X509_V_FLAG_USE_DELTAS; else if (!strcmp(arg, "-policy_print")) flags |= X509_V_FLAG_NOTIFY_POLICY; + else if (!strcmp(arg, "-check_ss_sig")) + flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; else return 0; @@ -2255,6 +2298,9 @@ int args_verify(char ***pargs, int *pargc, if (purpose) X509_VERIFY_PARAM_set_purpose(*pm, purpose); + if (depth >= 0) + X509_VERIFY_PARAM_set_depth(*pm, depth); + end: (*pargs)++; @@ -2266,6 +2312,61 @@ int args_verify(char ***pargs, int *pargc, } +/* Read whole contents of a BIO into an allocated memory buffer and + * return it. + */ + +int bio_to_mem(unsigned char **out, int maxlen, BIO *in) + { + BIO *mem; + int len, ret; + unsigned char tbuf[1024]; + mem = BIO_new(BIO_s_mem()); + if (!mem) + return -1; + for(;;) + { + if ((maxlen != -1) && maxlen < 1024) + len = maxlen; + else + len = 1024; + len = BIO_read(in, tbuf, len); + if (len <= 0) + break; + if (BIO_write(mem, tbuf, len) != len) + { + BIO_free(mem); + return -1; + } + maxlen -= len; + + if (maxlen == 0) + break; + } + ret = BIO_get_mem_data(mem, (char **)out); + BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); + BIO_free(mem); + return ret; + } + +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) + { + int rv; + char *stmp, *vtmp = NULL; + stmp = BUF_strdup(value); + if (!stmp) + return -1; + vtmp = strchr(stmp, ':'); + if (vtmp) + { + *vtmp = 0; + vtmp++; + } + rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); + OPENSSL_free(stmp); + return rv; + } + static void nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes) { @@ -2307,6 +2408,230 @@ void policies_print(BIO *out, X509_STORE_CTX *ctx) BIO_free(out); } +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) + +static JPAKE_CTX *jpake_init(const char *us, const char *them, + const char *secret) + { + BIGNUM *p = NULL; + BIGNUM *g = NULL; + BIGNUM *q = NULL; + BIGNUM *bnsecret = BN_new(); + JPAKE_CTX *ctx; + + /* Use a safe prime for p (that we found earlier) */ + BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F"); + g = BN_new(); + BN_set_word(g, 2); + q = BN_new(); + BN_rshift1(q, p); + + BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret); + + ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret); + BN_free(bnsecret); + BN_free(q); + BN_free(g); + BN_free(p); + + return ctx; + } + +static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p) + { + BN_print(conn, p->gx); + BIO_puts(conn, "\n"); + BN_print(conn, p->zkpx.gr); + BIO_puts(conn, "\n"); + BN_print(conn, p->zkpx.b); + BIO_puts(conn, "\n"); + } + +static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx) + { + JPAKE_STEP1 s1; + + JPAKE_STEP1_init(&s1); + JPAKE_STEP1_generate(&s1, ctx); + jpake_send_part(bconn, &s1.p1); + jpake_send_part(bconn, &s1.p2); + (void)BIO_flush(bconn); + JPAKE_STEP1_release(&s1); + } + +static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx) + { + JPAKE_STEP2 s2; + + JPAKE_STEP2_init(&s2); + JPAKE_STEP2_generate(&s2, ctx); + jpake_send_part(bconn, &s2); + (void)BIO_flush(bconn); + JPAKE_STEP2_release(&s2); + } + +static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx) + { + JPAKE_STEP3A s3a; + + JPAKE_STEP3A_init(&s3a); + JPAKE_STEP3A_generate(&s3a, ctx); + BIO_write(bconn, s3a.hhk, sizeof s3a.hhk); + (void)BIO_flush(bconn); + JPAKE_STEP3A_release(&s3a); + } + +static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx) + { + JPAKE_STEP3B s3b; + + JPAKE_STEP3B_init(&s3b); + JPAKE_STEP3B_generate(&s3b, ctx); + BIO_write(bconn, s3b.hk, sizeof s3b.hk); + (void)BIO_flush(bconn); + JPAKE_STEP3B_release(&s3b); + } + +static void readbn(BIGNUM **bn, BIO *bconn) + { + char buf[10240]; + int l; + + l = BIO_gets(bconn, buf, sizeof buf); + assert(l > 0); + assert(buf[l-1] == '\n'); + buf[l-1] = '\0'; + BN_hex2bn(bn, buf); + } + +static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn) + { + readbn(&p->gx, bconn); + readbn(&p->zkpx.gr, bconn); + readbn(&p->zkpx.b, bconn); + } + +static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn) + { + JPAKE_STEP1 s1; + + JPAKE_STEP1_init(&s1); + jpake_receive_part(&s1.p1, bconn); + jpake_receive_part(&s1.p2, bconn); + if(!JPAKE_STEP1_process(ctx, &s1)) + { + ERR_print_errors(bio_err); + exit(1); + } + JPAKE_STEP1_release(&s1); + } + +static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn) + { + JPAKE_STEP2 s2; + + JPAKE_STEP2_init(&s2); + jpake_receive_part(&s2, bconn); + if(!JPAKE_STEP2_process(ctx, &s2)) + { + ERR_print_errors(bio_err); + exit(1); + } + JPAKE_STEP2_release(&s2); + } + +static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn) + { + JPAKE_STEP3A s3a; + int l; + + JPAKE_STEP3A_init(&s3a); + l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk); + assert(l == sizeof s3a.hhk); + if(!JPAKE_STEP3A_process(ctx, &s3a)) + { + ERR_print_errors(bio_err); + exit(1); + } + JPAKE_STEP3A_release(&s3a); + } + +static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn) + { + JPAKE_STEP3B s3b; + int l; + + JPAKE_STEP3B_init(&s3b); + l = BIO_read(bconn, s3b.hk, sizeof s3b.hk); + assert(l == sizeof s3b.hk); + if(!JPAKE_STEP3B_process(ctx, &s3b)) + { + ERR_print_errors(bio_err); + exit(1); + } + JPAKE_STEP3B_release(&s3b); + } + +void jpake_client_auth(BIO *out, BIO *conn, const char *secret) + { + JPAKE_CTX *ctx; + BIO *bconn; + + BIO_puts(out, "Authenticating with JPAKE\n"); + + ctx = jpake_init("client", "server", secret); + + bconn = BIO_new(BIO_f_buffer()); + BIO_push(bconn, conn); + + jpake_send_step1(bconn, ctx); + jpake_receive_step1(ctx, bconn); + jpake_send_step2(bconn, ctx); + jpake_receive_step2(ctx, bconn); + jpake_send_step3a(bconn, ctx); + jpake_receive_step3b(ctx, bconn); + + BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); + + psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); + + BIO_pop(bconn); + BIO_free(bconn); + + JPAKE_CTX_free(ctx); + } + +void jpake_server_auth(BIO *out, BIO *conn, const char *secret) + { + JPAKE_CTX *ctx; + BIO *bconn; + + BIO_puts(out, "Authenticating with JPAKE\n"); + + ctx = jpake_init("server", "client", secret); + + bconn = BIO_new(BIO_f_buffer()); + BIO_push(bconn, conn); + + jpake_receive_step1(ctx, bconn); + jpake_send_step1(bconn, ctx); + jpake_receive_step2(ctx, bconn); + jpake_send_step2(bconn, ctx); + jpake_receive_step3a(ctx, bconn); + jpake_send_step3b(bconn, ctx); + + BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); + + psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); + + BIO_pop(bconn); + BIO_free(bconn); + + JPAKE_CTX_free(ctx); + } + +#endif + /* * Platform-specific sections */ @@ -2395,13 +2720,14 @@ double app_tminterval(int stop,int usertime) else #endif { + SYSTEMTIME systime; + if (usertime && warning) { BIO_printf(bio_err,"To get meaningful results, run " - "this program on idle system.\n" - warning=1; + "this program on idle system.\n"); + warning=0; } - SYSTEMTIME systime; GetSystemTime(&systime); SystemTimeToFileTime(&systime,&now); } @@ -2417,12 +2743,101 @@ double app_tminterval(int stop,int usertime) tmstop.u.LowPart = now.dwLowDateTime; tmstop.u.HighPart = now.dwHighDateTime; - ret = (tmstop.QuadPart - tmstart.QuadPart)*1e-7; + ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7; } return (ret); } +#elif defined(OPENSSL_SYS_NETWARE) +#include + +double app_tminterval(int stop,int usertime) + { + double ret=0; + static clock_t tmstart; + static int warning=1; + + if (usertime && warning) + { + BIO_printf(bio_err,"To get meaningful results, run " + "this program on idle system.\n"); + warning=0; + } + + if (stop==TM_START) tmstart = clock(); + else ret = (clock()-tmstart)/(double)CLOCKS_PER_SEC; + + return (ret); + } + +#elif defined(OPENSSL_SYSTEM_VXWORKS) +#include + +double app_tminterval(int stop,int usertime) + { + double ret=0; +#ifdef CLOCK_REALTIME + static struct timespec tmstart; + struct timespec now; +#else + static unsigned long tmstart; + unsigned long now; +#endif + static int warning=1; + + if (usertime && warning) + { + BIO_printf(bio_err,"To get meaningful results, run " + "this program on idle system.\n"); + warning=0; + } + +#ifdef CLOCK_REALTIME + clock_gettime(CLOCK_REALTIME,&now); + if (stop==TM_START) tmstart = now; + else ret = ( (now.tv_sec+now.tv_nsec*1e-9) + - (tmstart.tv_sec+tmstart.tv_nsec*1e-9) ); +#else + now = tickGet(); + if (stop==TM_START) tmstart = now; + else ret = (now - tmstart)/(double)sysClkRateGet(); +#endif + return (ret); + } + +#elif defined(OPENSSL_SYSTEM_VMS) +#include +#include + +double app_tminterval(int stop,int usertime) + { + static clock_t tmstart; + double ret = 0; + clock_t now; +#ifdef __TMS + struct tms rus; + + now = times(&rus); + if (usertime) now = rus.tms_utime; +#else + if (usertime) + now = clock(); /* sum of user and kernel times */ + else { + struct timeval tv; + gettimeofday(&tv,NULL); + now = (clock_t)( + (unsigned long long)tv.tv_sec*CLK_TCK + + (unsigned long long)tv.tv_usec*(1000000/CLK_TCK) + ); + } +#endif + if (stop==TM_START) tmstart = now; + else ret = (now - tmstart)/(double)(CLK_TCK); + + return (ret); + } + #elif defined(_SC_CLK_TCK) /* by means of unistd.h */ #include @@ -2436,7 +2851,11 @@ double app_tminterval(int stop,int usertime) if (usertime) now = rus.tms_utime; if (stop==TM_START) tmstart = now; - else ret = (now - tmstart)/(double)sysconf(_SC_CLK_TCK); + else + { + long int tck = sysconf(_SC_CLK_TCK); + ret = (now - tmstart)/(double)tck; + } return (ret); } @@ -2452,7 +2871,7 @@ double app_tminterval(int stop,int usertime) struct timeval now; static struct timeval tmstart; - if (usertime) getrusage(RUSAGE_SELF,&rus), now = rus.ru_time; + if (usertime) getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime; else gettimeofday(&now,NULL); if (stop==TM_START) tmstart = now; @@ -2527,7 +2946,7 @@ int raw_read_stdin(void *buf,int siz) #endif #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE) -int raw_write_stdout(void *buf,int siz) +int raw_write_stdout(const void *buf,int siz) { DWORD n; if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))