Synchronise VMS build system with the Unixly one
[openssl.git] / apps / apps.c
index be710a6adb1d76aea98c3977846fec672a9f85aa..56e87ecd3b2151d51718ccf714962148077cd28f 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifndef OPENSSL_SYSNAME_WIN32
+#include <strings.h>
+#endif
 #include <sys/types.h>
 #include <ctype.h>
 #include <errno.h>
+#include <assert.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/rsa.h>
 #endif
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_JPAKE
+#include <openssl/jpake.h>
+#endif
 
 #define NON_MAIN
 #include "apps.h"
@@ -1437,6 +1444,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)
@@ -1470,7 +1481,7 @@ char *make_config_name()
        return p;
        }
 
-static unsigned long index_serial_hash(const char **a)
+static unsigned long index_serial_hash(const CSTRING *a)
        {
        const char *n;
 
@@ -1479,7 +1490,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 CSTRING *a, const CSTRING *b)
        {
        const char *aa,*bb;
 
@@ -1491,17 +1502,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 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 CSTRING *a, const 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, CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_serial, CSTRING)
+static IMPLEMENT_LHASH_HASH_FN(index_name, CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_name, CSTRING)
 
 #undef BSIZE
 #define BSIZE 256
@@ -1734,10 +1744,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);
@@ -1798,8 +1805,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",
@@ -1809,8 +1816,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);
@@ -2026,7 +2033,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;
@@ -2230,8 +2237,16 @@ 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
@@ -2270,6 +2285,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)
        {
@@ -2311,6 +2381,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
  */
@@ -2428,7 +2722,7 @@ double app_tminterval(int stop,int usertime)
        return (ret);
        }
 
-#elif defined(OPENSSL_SYSTEM_NETWARE)
+#elif defined(OPENSSL_SYS_NETWARE)
 #include <time.h>
 
 double app_tminterval(int stop,int usertime)
@@ -2530,7 +2824,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);
        }
@@ -2546,7 +2844,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;
@@ -2621,7 +2919,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))