new option "openssl ciphers -V"
[openssl.git] / apps / apps.c
index e08c4bdebaa78c0a0c709c828af1627ef45a1819..a9ac9e1b6a7b4acea8f78ec2c642a983fa9a034e 100644 (file)
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
+#ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
+#endif
 #include <openssl/bn.h>
 
 #define NON_MAIN
 #undef NON_MAIN
 
 typedef struct {
-       char *name;
+       const char *name;
        unsigned long flag;
        unsigned long mask;
 } NAME_EX_TBL;
@@ -237,11 +239,18 @@ int str2fmt(char *s)
        else if ((*s == 'T') || (*s == 't'))
                return(FORMAT_TEXT);
        else if ((*s == 'P') || (*s == 'p'))
-               return(FORMAT_PEM);
-       else if ((*s == 'N') || (*s == 'n'))
-               return(FORMAT_NETSCAPE);
-       else if ((*s == 'S') || (*s == 's'))
-               return(FORMAT_SMIME);
+               {
+               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'))
+               return(FORMAT_SMIME);
+       else if ((*s == 'M') || (*s == 'm'))
+               return(FORMAT_MSBLOB);
        else if ((*s == '1')
                || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
                || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
@@ -374,10 +383,17 @@ int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
                /* The start of something good :-) */
                if (num >= arg->count)
                        {
-                       arg->count+=20;
-                       arg->data=(char **)OPENSSL_realloc(arg->data,
-                               sizeof(char *)*arg->count);
-                       if (argc == 0) return(0);
+                       char **tmp_p;
+                       int tlen = arg->count + 20;
+                       tmp_p = (char **)OPENSSL_realloc(arg->data,
+                               sizeof(char *)*tlen);
+                       if (tmp_p == NULL)
+                               return 0;
+                       arg->data  = tmp_p;
+                       arg->count = tlen;
+                       /* initialize newly allocated data */
+                       for (i = num; i < arg->count; i++)
+                               arg->data[i] = NULL;
                        }
                arg->data[num++]=p;
 
@@ -700,7 +716,7 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc,
        if (p12 == NULL)
                {
                BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);    
-               goto err;
+               goto die;
                }
        /* See if an empty password will do */
        if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
@@ -714,7 +730,7 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc,
                        {
                        BIO_printf(err, "Passpharse callback error for %s\n",
                                        desc);
-                       goto err;
+                       goto die;
                        }
                if (len < PEM_BUFSIZE)
                        tpass[len] = 0;
@@ -722,12 +738,12 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc,
                        {
                        BIO_printf(err,
        "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);    
-                       goto err;
+                       goto die;
                        }
                pass = tpass;
                }
        ret = PKCS12_parse(p12, pass, pkey, cert, ca);
-       err:
+       die:
        if (p12)
                PKCS12_free(p12);
        return ret;
@@ -736,8 +752,6 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc,
 X509 *load_cert(BIO *err, const char *file, int format,
        const char *pass, ENGINE *e, const char *cert_descrip)
        {
-       ASN1_HEADER *ah=NULL;
-       BUF_MEM *buf=NULL;
        X509 *x=NULL;
        BIO *cert;
 
@@ -767,46 +781,21 @@ X509 *load_cert(BIO *err, const char *file, int format,
                x=d2i_X509_bio(cert,NULL);
        else if (format == FORMAT_NETSCAPE)
                {
-               const unsigned char *p,*op;
-               int size=0,i;
-
-               /* We sort of have to do it this way because it is sort of nice
-                * to read the header first and check it, then
-                * try to read the certificate */
-               buf=BUF_MEM_new();
-               for (;;)
-                       {
-                       if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
+               NETSCAPE_X509 *nx;
+               nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
+               if (nx == NULL)
                                goto end;
-                       i=BIO_read(cert,&(buf->data[size]),1024*10);
-                       size+=i;
-                       if (i == 0) break;
-                       if (i < 0)
-                               {
-                               perror("reading certificate");
-                               goto end;
-                               }
-                       }
-               p=(unsigned char *)buf->data;
-               op=p;
 
-               /* First load the header */
-               if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
-                       goto end;
-               if ((ah->header == NULL) || (ah->header->data == NULL) ||
-                       (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data,
-                       ah->header->length) != 0))
+               if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
+                       nx->header->length) != 0))
                        {
+                       NETSCAPE_X509_free(nx);
                        BIO_printf(err,"Error reading header on certificate\n");
                        goto end;
                        }
-               /* header is ok, so now read the object */
-               p=op;
-               ah->meth=X509_asn1_meth();
-               if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
-                       goto end;
-               x=(X509 *)ah->data;
-               ah->data=NULL;
+               x=nx->cert;
+               nx->cert = NULL;
+               NETSCAPE_X509_free(nx);
                }
        else if (format == FORMAT_PEM)
                x=PEM_read_bio_X509_AUX(cert,NULL,
@@ -828,9 +817,7 @@ end:
                BIO_printf(err,"unable to load certificate\n");
                ERR_print_errors(err);
                }
-       if (ah != NULL) ASN1_HEADER_free(ah);
        if (cert != NULL) BIO_free(cert);
-       if (buf != NULL) BUF_MEM_free(buf);
        return(x);
        }
 
@@ -899,6 +886,11 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
                                &pkey, NULL, NULL))
                        goto end;
                }
+       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);
        else
                {
                BIO_printf(err,"bad input format specified for key file\n");
@@ -960,6 +952,36 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
                {
                pkey=d2i_PUBKEY_bio(key, NULL);
                }
+       else if (format == FORMAT_ASN1RSA)
+               {
+               RSA *rsa;
+               rsa = d2i_RSAPublicKey_bio(key, NULL);
+               if (rsa)
+                       {
+                       pkey = EVP_PKEY_new();
+                       if (pkey)
+                               EVP_PKEY_set1_RSA(pkey, rsa);
+                       RSA_free(rsa);
+                       }
+               else
+                       pkey = NULL;
+               }
+       else if (format == FORMAT_PEMRSA)
+               {
+               RSA *rsa;
+               rsa = PEM_read_bio_RSAPublicKey(key, NULL, 
+                       (pem_password_cb *)password_callback, &cb_data);
+               if (rsa)
+                       {
+                       pkey = EVP_PKEY_new();
+                       if (pkey)
+                               EVP_PKEY_set1_RSA(pkey, rsa);
+                       RSA_free(rsa);
+                       }
+               else
+                       pkey = NULL;
+               }
+
        else if (format == FORMAT_PEM)
                {
                pkey=PEM_read_bio_PUBKEY(key,NULL,
@@ -969,6 +991,8 @@ 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
+       else if (format == FORMAT_MSBLOB)
+               pkey = b2i_PublicKey_bio(key);
        else
                {
                BIO_printf(err,"bad input format specified for key file\n");
@@ -1269,7 +1293,7 @@ static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_T
        return 0;
 }
 
-void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags)
+void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
 {
        char *buf;
        char mline = 0;
@@ -1604,8 +1628,9 @@ int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
                {
                if (errno != ENOENT 
 #ifdef ENOTDIR
-                       && errno != ENOTDIR)
+                       && errno != ENOTDIR
 #endif
+                  )
                        goto err;
                }
        else
@@ -1774,7 +1799,7 @@ int index_index(CA_DB *db)
        return 1;
        }
 
-int save_index(char *dbfile, char *suffix, CA_DB *db)
+int save_index(const char *dbfile, const char *suffix, CA_DB *db)
        {
        char buf[3][BSIZE];
        BIO *out = BIO_new(BIO_s_file());
@@ -1841,7 +1866,7 @@ int save_index(char *dbfile, char *suffix, CA_DB *db)
        return 0;
        }
 
-int rotate_index(char *dbfile, char *new_suffix, char *old_suffix)
+int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
        {
        char buf[5][BSIZE];
        int i,j;
@@ -1893,8 +1918,9 @@ int rotate_index(char *dbfile, char *new_suffix, char *old_suffix)
                {
                if (errno != ENOENT 
 #ifdef ENOTDIR
-                       && errno != ENOTDIR)
+                       && errno != ENOTDIR
 #endif
+                  )
                        goto err;
                }
        else
@@ -1929,8 +1955,9 @@ int rotate_index(char *dbfile, char *new_suffix, char *old_suffix)
                {
                if (errno != ENOENT 
 #ifdef ENOTDIR
-                       && errno != ENOTDIR)
+                       && errno != ENOTDIR
 #endif
+                  )
                        goto err;
                }
        else
@@ -1979,7 +2006,7 @@ void free_index(CA_DB *db)
                }
        }
 
-int parse_yesno(char *str, int def)
+int parse_yesno(const char *str, int def)
        {
        int ret = def;
        if (str)
@@ -2146,7 +2173,7 @@ error:
 
 /* This code MUST COME AFTER anything that uses rename() */
 #ifdef OPENSSL_SYS_WIN32
-int WIN32_rename(char *from, char *to)
+int WIN32_rename(const char *from, const char *to)
        {
 #ifndef OPENSSL_SYS_WINCE
        /* Windows rename gives an error if 'to' exists, so delete it
@@ -2281,7 +2308,8 @@ int args_verify(char ***pargs, int *pargc,
 
        }
 
-static void nodes_print(BIO *out, char *name, STACK_OF(X509_POLICY_NODE) *nodes)
+static void nodes_print(BIO *out, const char *name,
+       STACK_OF(X509_POLICY_NODE) *nodes)
        {
        X509_POLICY_NODE *node;
        int i;