Add 'rsautl' low level RSA utility.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 3 Sep 2000 23:13:48 +0000 (23:13 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 3 Sep 2000 23:13:48 +0000 (23:13 +0000)
Add DER public key routines.

Add -passin argument to 'ca' utility.

Document sign and verify options to dgst.

12 files changed:
CHANGES
apps/Makefile.ssl
apps/apps.c
apps/apps.h
apps/ca.c
apps/progs.h
apps/progs.pl
apps/rsautl.c [new file with mode: 0644]
crypto/x509/x509.h
crypto/x509/x_all.c
doc/apps/ca.pod
doc/apps/dgst.pod

diff --git a/CHANGES b/CHANGES
index dde9f64a99d020868b977af3a8cbe515f797f0b4..424a25c1e864047cdedbee65c8fd4148ae9178da 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
+  *) New openssl application 'rsautl'. This utility can be
+     used for low level RSA operations. DER public key
+     BIO/fp routines also added.
+     [Steve Henson]
+
   *) New Configure entry and patches for compiling on QNX 4.
      [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
 
   *) New Configure entry and patches for compiling on QNX 4.
      [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
 
index 7681d24b2961ee8c8b888b38282642d21413d60f..85fae40e77da84eef6507728e1f4b3140abaa9e4 100644 (file)
@@ -35,7 +35,7 @@ SCRIPTS=CA.sh CA.pl der_chop
 EXE= $(PROGRAM)
 
 E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
 EXE= $(PROGRAM)
 
 E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
-       ca crl rsa dsa dsaparam \
+       ca crl rsa rsautl dsa dsaparam \
        x509 genrsa gendsa s_server s_client speed \
        s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \
        pkcs8 spkac smime rand
        x509 genrsa gendsa s_server s_client speed \
        s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \
        pkcs8 spkac smime rand
@@ -51,14 +51,14 @@ RAND_SRC=app_rand.c
 
 E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
        ca.o pkcs7.o crl2p7.o crl.o \
 
 E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
        ca.o pkcs7.o crl2p7.o crl.o \
-       rsa.o dsa.o dsaparam.o \
+       rsa.o rsautl.o dsa.o dsaparam.o \
        x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
        s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
        ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o smime.o rand.o
 
 E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
        pkcs7.c crl2p7.c crl.c \
        x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
        s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
        ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o smime.o rand.o
 
 E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
        pkcs7.c crl2p7.c crl.c \
-       rsa.c dsa.c dsaparam.c \
+       rsa.c rsautl.c dsa.c dsaparam.c \
        x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
        s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
        ciphers.c nseq.c pkcs12.c pkcs8.c spkac.c smime.c rand.c
        x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
        s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
        ciphers.c nseq.c pkcs12.c pkcs8.c spkac.c smime.c rand.c
index 7ae7c77ca61ebc4b791ea737f8856faef7425fda..e5a42d4d97d7b2505092f9de9087514e4a091079 100644 (file)
@@ -592,6 +592,47 @@ EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass)
        return(pkey);
        }
 
        return(pkey);
        }
 
+EVP_PKEY *load_pubkey(BIO *err, char *file, int format)
+       {
+       BIO *key=NULL;
+       EVP_PKEY *pkey=NULL;
+
+       if (file == NULL)
+               {
+               BIO_printf(err,"no keyfile specified\n");
+               goto end;
+               }
+       key=BIO_new(BIO_s_file());
+       if (key == NULL)
+               {
+               ERR_print_errors(err);
+               goto end;
+               }
+       if (BIO_read_filename(key,file) <= 0)
+               {
+               perror(file);
+               goto end;
+               }
+       if (format == FORMAT_ASN1)
+               {
+               pkey=d2i_PUBKEY_bio(key, NULL);
+               }
+       else if (format == FORMAT_PEM)
+               {
+               pkey=PEM_read_bio_PUBKEY(key,NULL,NULL,NULL);
+               }
+       else
+               {
+               BIO_printf(err,"bad input format specified for key\n");
+               goto end;
+               }
+ end:
+       if (key != NULL) BIO_free(key);
+       if (pkey == NULL)
+               BIO_printf(err,"unable to load Public Key\n");
+       return(pkey);
+       }
+
 STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
        {
        BIO *certs;
 STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
        {
        BIO *certs;
index c44b21457a62ef4a7e5917acd1ccbce61d6034ea..151a94e9195db35bc338a1d6d80e6d376a7258eb 100644 (file)
@@ -152,6 +152,7 @@ int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
 int add_oid_section(BIO *err, LHASH *conf);
 X509 *load_cert(BIO *err, char *file, int format);
 EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass);
 int add_oid_section(BIO *err, LHASH *conf);
 X509 *load_cert(BIO *err, char *file, int format);
 EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass);
+EVP_PKEY *load_pubkey(BIO *err, char *file, int format);
 STACK_OF(X509) *load_certs(BIO *err, char *file, int format);
 
 #define FORMAT_UNDEF    0
 STACK_OF(X509) *load_certs(BIO *err, char *file, int format);
 
 #define FORMAT_UNDEF    0
index d28cde99d8c8ecb34397d948842d6da91b852c36..09314019929500072a0f3449a5c97f5d829e9ca1 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -216,7 +216,7 @@ int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
        {
 
 int MAIN(int argc, char **argv)
        {
-       char *key=NULL;
+       char *key=NULL,*passargin=NULL;
        int total=0;
        int total_done=0;
        int badops=0;
        int total=0;
        int total_done=0;
        int badops=0;
@@ -333,6 +333,11 @@ EF_ALIGNMENT=0;
                        if (--argc < 1) goto bad;
                        keyfile= *(++argv);
                        }
                        if (--argc < 1) goto bad;
                        keyfile= *(++argv);
                        }
+               else if (strcmp(*argv,"-passin") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       passargin= *(++argv);
+                       }
                else if (strcmp(*argv,"-key") == 0)
                        {
                        if (--argc < 1) goto bad;
                else if (strcmp(*argv,"-key") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -526,6 +531,11 @@ bad:
                lookup_fail(section,ENV_PRIVATE_KEY);
                goto err;
                }
                lookup_fail(section,ENV_PRIVATE_KEY);
                goto err;
                }
+       if(!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
+               {
+               BIO_printf(bio_err,"Error getting password\n");
+               goto err;
+               }
        if (BIO_read_filename(in,keyfile) <= 0)
                {
                perror(keyfile);
        if (BIO_read_filename(in,keyfile) <= 0)
                {
                perror(keyfile);
index 66fe42e1e90a0a6150d418598c6062b4cffd754a..fbc65de632cceadc3a162c35f2552e4adcef978d 100644 (file)
@@ -14,6 +14,7 @@ extern int errstr_main(int argc,char *argv[]);
 extern int ca_main(int argc,char *argv[]);
 extern int crl_main(int argc,char *argv[]);
 extern int rsa_main(int argc,char *argv[]);
 extern int ca_main(int argc,char *argv[]);
 extern int crl_main(int argc,char *argv[]);
 extern int rsa_main(int argc,char *argv[]);
+extern int rsautl_main(int argc,char *argv[]);
 extern int dsa_main(int argc,char *argv[]);
 extern int dsaparam_main(int argc,char *argv[]);
 extern int x509_main(int argc,char *argv[]);
 extern int dsa_main(int argc,char *argv[]);
 extern int dsaparam_main(int argc,char *argv[]);
 extern int x509_main(int argc,char *argv[]);
@@ -67,6 +68,9 @@ FUNCTION functions[] = {
 #ifndef NO_RSA
        {FUNC_TYPE_GENERAL,"rsa",rsa_main},
 #endif
 #ifndef NO_RSA
        {FUNC_TYPE_GENERAL,"rsa",rsa_main},
 #endif
+#ifndef NO_RSA
+       {FUNC_TYPE_GENERAL,"rsautl",rsautl_main},
+#endif
 #ifndef NO_DSA
        {FUNC_TYPE_GENERAL,"dsa",dsa_main},
 #endif
 #ifndef NO_DSA
        {FUNC_TYPE_GENERAL,"dsa",dsa_main},
 #endif
index 3d5e8de221aac6d07e32248974fa0cc4d832419d..214025cd2d6916d34984873699b8681ffca7d12c 100644 (file)
@@ -29,7 +29,7 @@ foreach (@ARGV)
        $str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n";
        if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/))
                { print "#if !defined(NO_SOCK) && !(defined(NO_SSL2) && defined(NO_SSL3))\n${str}#endif\n"; } 
        $str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n";
        if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/))
                { print "#if !defined(NO_SOCK) && !(defined(NO_SSL2) && defined(NO_SSL3))\n${str}#endif\n"; } 
-       elsif ( ($_ =~ /^rsa$/) || ($_ =~ /^genrsa$/) ) 
+       elsif ( ($_ =~ /^rsa$/) || ($_ =~ /^genrsa$/) || ($_ =~ /^rsautl$/)
                { print "#ifndef NO_RSA\n${str}#endif\n";  }
        elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/))
                { print "#ifndef NO_DSA\n${str}#endif\n"; }
                { print "#ifndef NO_RSA\n${str}#endif\n";  }
        elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/))
                { print "#ifndef NO_DSA\n${str}#endif\n"; }
diff --git a/apps/rsautl.c b/apps/rsautl.c
new file mode 100644 (file)
index 0000000..3a58b45
--- /dev/null
@@ -0,0 +1,276 @@
+/* rsautl.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 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
+ *    licensing@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 "apps.h"
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+#define RSA_SIGN       1
+#define RSA_VERIFY     2
+#define RSA_ENCRYPT    3
+#define RSA_DECRYPT    4
+
+#define KEY_PRIVKEY    1
+#define KEY_PUBKEY     2
+#define KEY_CERT       3
+
+static void usage(void);
+
+#undef PROG
+
+#define PROG rsautl_main
+
+int MAIN(int argc, char **);
+
+int MAIN(int argc, char **argv)
+{
+       BIO *in = NULL, *out = NULL;
+       char *infile = NULL, *outfile = NULL;
+       char *keyfile = NULL;
+       char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
+       int keyform = FORMAT_PEM;
+       char need_priv = 0, badarg = 0, rev = 0;
+       char hexdump = 0, asn1parse = 0;
+       X509 *x;
+       EVP_PKEY *pkey = NULL;
+       RSA *rsa = NULL;
+       unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
+       int rsa_inlen, rsa_outlen = 0;
+       int keysize;
+
+       int ret = 1;
+
+       argc--;
+       argv++;
+
+       if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+       ERR_load_crypto_strings();
+       OpenSSL_add_all_algorithms();
+       pad = RSA_PKCS1_PADDING;
+       
+       while(argc >= 1)
+       {
+               if (!strcmp(*argv,"-in")) {
+                       if (--argc < 1) badarg = 1;
+                        infile= *(++argv);
+               } else if (!strcmp(*argv,"-out")) {
+                       if (--argc < 1) badarg = 1;
+                       outfile= *(++argv);
+               } else if(!strcmp(*argv, "-inkey")) {
+                       if (--argc < 1) badarg = 1;
+                       keyfile = *(++argv);
+               } else if(!strcmp(*argv, "-pubin")) {
+                       key_type = KEY_PUBKEY;
+               } else if(!strcmp(*argv, "-certin")) {
+                       key_type = KEY_CERT;
+               } 
+               else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
+               else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
+               else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
+               else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
+               else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
+               else if(!strcmp(*argv, "-sign")) {
+                       rsa_mode = RSA_SIGN;
+                       need_priv = 1;
+               } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
+               else if(!strcmp(*argv, "-rev")) rev = 1;
+               else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
+               else if(!strcmp(*argv, "-decrypt")) {
+                       rsa_mode = RSA_DECRYPT;
+                       need_priv = 1;
+               } else badarg = 1;
+               if(badarg) {
+                       usage();
+                       goto end;
+               }
+               argc--;
+               argv++;
+       }
+
+       if(need_priv && (key_type == KEY_PRIVKEY)) {
+               BIO_printf(bio_err, "A private key is needed for this operation\n");
+               goto end;
+       }
+
+       switch(key_type) {
+               case KEY_PRIVKEY:
+               pkey = load_key(bio_err, keyfile, keyform, NULL);
+               break;
+
+               case KEY_PUBKEY:
+               pkey = load_pubkey(bio_err, keyfile, keyform);
+               break;
+
+               case KEY_CERT:
+               x = load_cert(bio_err, keyfile, keyform);
+               if(x) {
+                       pkey = X509_get_pubkey(x);
+                       X509_free(x);
+               }
+               break;
+       }
+
+       if(!pkey) {
+               BIO_printf(bio_err, "Error loading key\n");
+               return 1;
+       }
+
+       rsa = EVP_PKEY_get1_RSA(pkey);
+       EVP_PKEY_free(pkey);
+
+       if(!rsa) {
+               BIO_printf(bio_err, "Error getting RSA key\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+
+
+       if(infile) {
+               if(!(in = BIO_new_file(infile, "rb"))) {
+                       BIO_printf(bio_err, "Error Reading Input File\n");
+                       ERR_print_errors(bio_err);      
+                       goto end;
+               }
+       } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+       if(outfile) {
+               if(!(out = BIO_new_file(outfile, "wb"))) {
+                       BIO_printf(bio_err, "Error Reading Output File\n");
+                       ERR_print_errors(bio_err);      
+                       goto end;
+               }
+       } else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+       keysize = RSA_size(rsa);
+
+       rsa_in = OPENSSL_malloc(keysize * 2);
+       rsa_out = OPENSSL_malloc(keysize);
+
+       /* Read the input data */
+       rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
+       if(rsa_inlen <= 0) {
+               BIO_printf(bio_err, "Error reading input Data\n");
+               exit(1);
+       }
+       if(rev) {
+               int i;
+               unsigned char ctmp;
+               for(i = 0; i < rsa_inlen/2; i++) {
+                       ctmp = rsa_in[i];
+                       rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
+                       rsa_in[rsa_inlen - 1 - i] = ctmp;
+               }
+       }
+       switch(rsa_mode) {
+
+               case RSA_VERIFY:
+                       rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+               break;
+
+               case RSA_SIGN:
+                       rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+               break;
+
+               case RSA_ENCRYPT:
+                       rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+               break;
+
+               case RSA_DECRYPT:
+                       rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+               break;
+
+       }
+
+       if(rsa_outlen <= 0) {
+               BIO_printf(bio_err, "RSA operation error\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+       ret = 0;
+       if(asn1parse) {
+               if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
+                       ERR_print_errors(bio_err);
+               }
+       } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
+       else BIO_write(out, rsa_out, rsa_outlen);
+       end:
+       RSA_free(rsa);
+       BIO_free(in);
+       BIO_free(out);
+       if(rsa_in) OPENSSL_free(rsa_in);
+       if(rsa_out) OPENSSL_free(rsa_out);
+       return ret;
+}
+
+static void usage()
+{
+       BIO_printf(bio_err, "Usage: rsautl [options]\n");
+       BIO_printf(bio_err, "-in file        input file\n");
+       BIO_printf(bio_err, "-out file       output file\n");
+       BIO_printf(bio_err, "-inkey file     input key\n");
+       BIO_printf(bio_err, "-pubin          input is an RSA public\n");
+       BIO_printf(bio_err, "-certin         input is a certificate carrying an RSA public key\n");
+       BIO_printf(bio_err, "-ssl            use SSL v2 padding\n");
+       BIO_printf(bio_err, "-raw            use no padding\n");
+       BIO_printf(bio_err, "-pkcs           use PKCS#1 padding (default)\n");
+       BIO_printf(bio_err, "-sign           sign with private key\n");
+       BIO_printf(bio_err, "-verify         verify with public key\n");
+       BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
+       BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
+       BIO_printf(bio_err, "-hexdump        hex dump output\n");
+}
+
index ffa6e01251f34b985bd30613e37293031a1c41d6..7808b6a1120c02951cc80538b5057d33672306eb 100644 (file)
@@ -744,6 +744,8 @@ int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
 int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
 int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
 int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
 int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 #endif
 
 #ifndef NO_BIO
 #endif
 
 #ifndef NO_BIO
@@ -775,6 +777,8 @@ int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
 int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
 int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
 int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
 int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
 #endif
 
 X509 *X509_dup(X509 *x509);
 #endif
 
 X509 *X509_dup(X509 *x509);
index dd5796e205d2f5d4571d85cb21514a3ca5af331b..9bd6e2a39bd6d2fe049ec806ed3beabea84f5d46 100644 (file)
@@ -504,6 +504,17 @@ EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
                (char *(*)())d2i_AutoPrivateKey, (fp),(unsigned char **)(a)));
 }
 
                (char *(*)())d2i_AutoPrivateKey, (fp),(unsigned char **)(a)));
 }
 
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
+       {
+       return(ASN1_i2d_fp(i2d_PUBKEY,fp,(unsigned char *)pkey));
+       }
+
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
+{
+       return((EVP_PKEY *)ASN1_d2i_fp((char *(*)())EVP_PKEY_new,
+               (char *(*)())d2i_PUBKEY, (fp),(unsigned char **)(a)));
+}
+
 #endif
 
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
 #endif
 
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
@@ -541,3 +552,14 @@ EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
        return((EVP_PKEY *)ASN1_d2i_bio((char *(*)())EVP_PKEY_new,
                (char *(*)())d2i_AutoPrivateKey, (bp),(unsigned char **)(a)));
        }
        return((EVP_PKEY *)ASN1_d2i_bio((char *(*)())EVP_PKEY_new,
                (char *(*)())d2i_AutoPrivateKey, (bp),(unsigned char **)(a)));
        }
+
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
+       {
+       return(ASN1_i2d_bio(i2d_PUBKEY,bp,(unsigned char *)pkey));
+       }
+
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
+       {
+       return((EVP_PKEY *)ASN1_d2i_bio((char *(*)())EVP_PKEY_new,
+               (char *(*)())d2i_PUBKEY, (bp),(unsigned char **)(a)));
+       }
index efe1b3c23084a22a51c58652ff1c5eb6e7d5e8c3..d35292586458c2bbb23fa7fac0058c423d517654 100644 (file)
@@ -23,6 +23,7 @@ B<openssl> B<ca>
 [B<-policy arg>]
 [B<-keyfile arg>]
 [B<-key arg>]
 [B<-policy arg>]
 [B<-keyfile arg>]
 [B<-key arg>]
+[B<-passin arg>]
 [B<-cert file>]
 [B<-in file>]
 [B<-out file>]
 [B<-cert file>]
 [B<-in file>]
 [B<-out file>]
@@ -99,6 +100,10 @@ the password used to encrypt the private key. Since on some
 systems the command line arguments are visible (e.g. Unix with
 the 'ps' utility) this option should be used with caution.
 
 systems the command line arguments are visible (e.g. Unix with
 the 'ps' utility) this option should be used with caution.
 
+=item B<-passin arg>
+
+the key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
 =item B<-verbose>
 
 this prints extra details about the operations being performed.
 =item B<-verbose>
 
 this prints extra details about the operations being performed.
index fcfd3ecf23f4f948b3bee19dfcf19b4bc5459f28..6fbf4339abc2272ab7d3d0e663acc0cbd9ea7c3c 100644 (file)
@@ -7,9 +7,16 @@ dgst, md5, md2, sha1, sha, mdc2, ripemd160 - message digests
 =head1 SYNOPSIS
 
 B<openssl> B<dgst> 
 =head1 SYNOPSIS
 
 B<openssl> B<dgst> 
-[B<-md5|-md2|-sha1|-sha|mdc2|-ripemd160>]
+[B<-md5|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1>]
 [B<-c>]
 [B<-d>]
 [B<-c>]
 [B<-d>]
+[B<-hex>]
+[B<-binary>]
+[B<-out filename>]
+[B<-sign filename>]
+[B<-verify filename>]
+[B<-prverify filename>]
+[B<-signature filename>]
 [B<file...>]
 
 [B<md5|md2|sha1|sha|mdc2|ripemd160>]
 [B<file...>]
 
 [B<md5|md2|sha1|sha|mdc2|ripemd160>]
@@ -19,8 +26,8 @@ B<openssl> B<dgst>
 
 =head1 DESCRIPTION
 
 
 =head1 DESCRIPTION
 
-The digest functions print out the message digest of a supplied file or files
-in hexadecimal form.
+The digest functions output the message digest of a supplied file or files
+in hexadecimal form. They can also be used for digital signing and verification.
 
 =head1 OPTIONS
 
 
 =head1 OPTIONS
 
@@ -28,12 +35,51 @@ in hexadecimal form.
 
 =item B<-c>
 
 
 =item B<-c>
 
-print out the digest in two digit groups separated by colons.
+print out the digest in two digit groups separated by colons, only relevant if
+B<hex> format output is used.
 
 =item B<-d>
 
 print out BIO debugging information.
 
 
 =item B<-d>
 
 print out BIO debugging information.
 
+=item B<-hex>
+
+digest is to be output as a hex dump. This is the default case for a "normal"
+digest as opposed to a digital signature.
+
+=item B<-binary>
+
+output the digest or signature in binary form.
+
+=item B<-out filename>
+
+filename to output to, or standard output by default.
+
+=item B<-sign filename>
+
+digitally sign the digest using the private key in "filename".
+
+=item B<-verify filename>
+
+verify the signature using the the public key in "filename".
+The output is either "Verification OK" or "Verification Failure".
+
+=item B<-prverify filename>
+
+verify the signature using the  the private key in "filename".
+
+=item B<-signature filename>
+
+the actual signature to verify.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others. 
+
 =item B<file...>
 
 file or files to digest. If no files are specified then standard input is
 =item B<file...>
 
 file or files to digest. If no files are specified then standard input is
@@ -46,4 +92,13 @@ used.
 The digest of choice for all new applications is SHA1. Other digests are
 however still widely used.
 
 The digest of choice for all new applications is SHA1. Other digests are
 however still widely used.
 
+If you wish to sign or verify data using the DSA algorithm then the dss1
+digest must be used.
+
+A source of random numbers is required for certain signing algorithms, in
+particular DSA.
+
+The signing and verify options should only be used if a single file is
+being signed or verified.
+
 =cut
 =cut