PR: 1956
[openssl.git] / apps / apps.c
index 43eae05dec21371174a105537a0750643c2836d4..47413f58273f9ce1c1f6f46254fef109c396d5e6 100644 (file)
  *
  */
 
+#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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#ifndef OPENSSL_SYSNAME_WIN32
+#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB)
 #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"
@@ -255,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'))
@@ -274,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);
        }
@@ -917,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");
@@ -985,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;
@@ -1014,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,
@@ -1024,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");
@@ -2235,8 +2246,14 @@ int args_verify(char ***pargs, int *pargc,
                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
@@ -2371,6 +2388,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
  */