Add support for public key input and output in rsa and dsa utilities with some
authorDr. Stephen Henson <steve@openssl.org>
Mon, 4 Oct 1999 21:17:47 +0000 (21:17 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 4 Oct 1999 21:17:47 +0000 (21:17 +0000)
new DSA public key functions that were missing.

Also beginning of a cache for X509_EXTENSION structures: this will allow them
to be accessed more quickly for things like certificate chain verification...

CHANGES
apps/dsa.c
apps/rsa.c
crypto/asn1/x_exten.c
crypto/pem/pem.h
crypto/pem/pem_all.c
crypto/x509/x509.h
crypto/x509/x_all.c

diff --git a/CHANGES b/CHANGES
index a7339e67e1495949543fb54eefcc116833523bf3..4e9fef40c12a9714a1e2e87dba248fb261fe27d3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Add -pubin and -pubout options to the rsa and dsa commands. These allow
+     a public key to be input or output. For example:
+     openssl rsa -in key.pem -pubout -out pubkey.pem
+     Also added necessary DSA public key functions to handle this.
+     [Steve Henson]
+
   *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained
      in the message. This was handled by allowing
      X509_find_by_issuer_and_serial() to tolerate a NULL passed to it.
index fedecf27397bc51095fd3adf3dcd5e50bf1014e0..6117fc4b2d9aedba5ccfccc07df5c3976ca70048 100644 (file)
@@ -91,6 +91,7 @@ int MAIN(int argc, char **argv)
        const EVP_CIPHER *enc=NULL;
        BIO *in=NULL,*out=NULL;
        int informat,outformat,text=0,noout=0;
+       int pubin = 0, pubout = 0;
        char *infile,*outfile,*prog;
        int modulus=0;
 
@@ -136,6 +137,10 @@ int MAIN(int argc, char **argv)
                        text=1;
                else if (strcmp(*argv,"-modulus") == 0)
                        modulus=1;
+               else if (strcmp(*argv,"-pubin") == 0)
+                       pubin=1;
+               else if (strcmp(*argv,"-pubout") == 0)
+                       pubout=1;
                else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -187,19 +192,21 @@ bad:
                        }
                }
 
-       BIO_printf(bio_err,"read DSA private key\n");
-       if      (informat == FORMAT_ASN1)
-               dsa=d2i_DSAPrivateKey_bio(in,NULL);
-       else if (informat == FORMAT_PEM)
-               dsa=PEM_read_bio_DSAPrivateKey(in,NULL,NULL,NULL);
-       else
+       BIO_printf(bio_err,"read DSA key\n");
+       if      (informat == FORMAT_ASN1) {
+               if(pubin) dsa=d2i_DSAPublicKey_bio(in,NULL);
+               else dsa=d2i_DSAPrivateKey_bio(in,NULL);
+       } else if (informat == FORMAT_PEM) {
+               if(pubin) dsa=PEM_read_bio_DSAPublicKey(in,NULL, NULL, NULL);
+               else dsa=PEM_read_bio_DSAPrivateKey(in,NULL,NULL,NULL);
+       } else
                {
                BIO_printf(bio_err,"bad input format specified for key\n");
                goto end;
                }
        if (dsa == NULL)
                {
-               BIO_printf(bio_err,"unable to load Private Key\n");
+               BIO_printf(bio_err,"unable to load Key\n");
                ERR_print_errors(bio_err);
                goto end;
                }
@@ -231,12 +238,15 @@ bad:
                }
 
        if (noout) goto end;
-       BIO_printf(bio_err,"writing DSA private key\n");
-       if      (outformat == FORMAT_ASN1)
-               i=i2d_DSAPrivateKey_bio(out,dsa);
-       else if (outformat == FORMAT_PEM)
-               i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL,NULL);
-       else    {
+       BIO_printf(bio_err,"writing DSA key\n");
+       if      (outformat == FORMAT_ASN1) {
+               if(pubin || pubout) i=i2d_DSAPublicKey_bio(out,dsa);
+               else i=i2d_DSAPrivateKey_bio(out,dsa);
+       } else if (outformat == FORMAT_PEM) {
+               if(pubin || pubout)
+                       i=PEM_write_bio_DSAPublicKey(out,dsa);
+               else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL,NULL);
+       } else  {
                BIO_printf(bio_err,"bad output format specified for outfile\n");
                goto end;
                }
index dd58a179a5ecbfc7844858107f4ce0f20f4de9ae..0351cb7d229a80a6d5b8d993436534deb59f402a 100644 (file)
@@ -82,6 +82,8 @@
  * -text       - print a text version
  * -modulus    - print the RSA key modulus
  * -check      - verify key consistency
+ * -pubin      - Expect a public key in input file.
+ * -pubout     - Output a public key.
  */
 
 int MAIN(int argc, char **argv)
@@ -92,6 +94,7 @@ int MAIN(int argc, char **argv)
        const EVP_CIPHER *enc=NULL;
        BIO *in=NULL,*out=NULL;
        int informat,outformat,text=0,check=0,noout=0;
+       int pubin = 0, pubout = 0;
        char *infile,*outfile,*prog;
        int modulus=0;
 
@@ -131,6 +134,10 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        outfile= *(++argv);
                        }
+               else if (strcmp(*argv,"-pubin") == 0)
+                       pubin=1;
+               else if (strcmp(*argv,"-pubout") == 0)
+                       pubout=1;
                else if (strcmp(*argv,"-noout") == 0)
                        noout=1;
                else if (strcmp(*argv,"-text") == 0)
@@ -167,6 +174,8 @@ bad:
                BIO_printf(bio_err," -noout        don't print key out\n");
                BIO_printf(bio_err," -modulus      print the RSA key modulus\n");
                BIO_printf(bio_err," -check        verify key consistency\n");
+               BIO_printf(bio_err," -pubin        expect a public key in input file\n");
+               BIO_printf(bio_err," -pubout       output a public key\n");
                goto end;
                }
 
@@ -192,8 +201,10 @@ bad:
                }
 
        BIO_printf(bio_err,"read RSA private key\n");
-       if      (informat == FORMAT_ASN1)
-               rsa=d2i_RSAPrivateKey_bio(in,NULL);
+       if      (informat == FORMAT_ASN1) {
+               if (pubin) rsa=d2i_RSAPublicKey_bio(in,NULL);
+               else rsa=d2i_RSAPrivateKey_bio(in,NULL);
+       }
 #ifndef NO_RC4
        else if (informat == FORMAT_NETSCAPE)
                {
@@ -221,8 +232,10 @@ bad:
                BUF_MEM_free(buf);
                }
 #endif
-       else if (informat == FORMAT_PEM)
-               rsa=PEM_read_bio_RSAPrivateKey(in,NULL,NULL,NULL);
+       else if (informat == FORMAT_PEM) {
+               if(pubin) rsa=PEM_read_bio_RSAPublicKey(in,NULL,NULL,NULL);
+               else rsa=PEM_read_bio_RSAPrivateKey(in,NULL,NULL,NULL);
+       }
        else
                {
                BIO_printf(bio_err,"bad input format specified for key\n");
@@ -230,7 +243,7 @@ bad:
                }
        if (rsa == NULL)
                {
-               BIO_printf(bio_err,"unable to load Private Key\n");
+               BIO_printf(bio_err,"unable to load Key\n");
                ERR_print_errors(bio_err);
                goto end;
                }
@@ -293,9 +306,11 @@ bad:
                ret = 0;
                goto end;
                }
-       BIO_printf(bio_err,"writing RSA private key\n");
-       if      (outformat == FORMAT_ASN1)
-               i=i2d_RSAPrivateKey_bio(out,rsa);
+       BIO_printf(bio_err,"writing RSA key\n");
+       if      (outformat == FORMAT_ASN1) {
+               if(pubout || pubin) i=i2d_RSAPublicKey_bio(out,rsa);
+               else i=i2d_RSAPrivateKey_bio(out,rsa);
+       }
 #ifndef NO_RC4
        else if (outformat == FORMAT_NETSCAPE)
                {
@@ -315,15 +330,18 @@ bad:
                Free(pp);
                }
 #endif
-       else if (outformat == FORMAT_PEM)
-               i=PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0,NULL,NULL);
-       else    {
+       else if (outformat == FORMAT_PEM) {
+               if(pubout || pubin)
+                   i=PEM_write_bio_RSAPublicKey(out,rsa);
+               else
+                   i=PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0,NULL,NULL);
+       } else  {
                BIO_printf(bio_err,"bad output format specified for outfile\n");
                goto end;
                }
        if (!i)
                {
-               BIO_printf(bio_err,"unable to write private key\n");
+               BIO_printf(bio_err,"unable to write key\n");
                ERR_print_errors(bio_err);
                }
        else
index d5f9e1df9e0e3e55921b31fd0f25e39c80c42588..f5931f762383c9bc9cd229e7f3da5a1941d6c986 100644 (file)
@@ -100,10 +100,6 @@ X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **a, unsigned char **pp,
        M_ASN1_D2I_start_sequence();
        M_ASN1_D2I_get(ret->object,d2i_ASN1_OBJECT);
 
-       if ((ret->argp != NULL) && (ret->ex_free != NULL))
-               ret->ex_free(ret);
-       ret->argl=0;
-       ret->argp=NULL;
        ret->netscape_hack=0;
        if ((c.slen != 0) &&
                (M_ASN1_next == (V_ASN1_UNIVERSAL|V_ASN1_BOOLEAN)))
@@ -129,9 +125,6 @@ X509_EXTENSION *X509_EXTENSION_new(void)
        M_ASN1_New(ret->value,ASN1_OCTET_STRING_new);
        ret->critical=0;
        ret->netscape_hack=0;
-       ret->argl=0L;
-       ret->argp=NULL;
-       ret->ex_free=NULL;
        return(ret);
        M_ASN1_New_Error(ASN1_F_X509_EXTENSION_NEW);
        }
@@ -139,8 +132,6 @@ X509_EXTENSION *X509_EXTENSION_new(void)
 void X509_EXTENSION_free(X509_EXTENSION *a)
        {
        if (a == NULL) return;
-       if ((a->argp != NULL) && (a->ex_free != NULL))
-               a->ex_free(a);
        ASN1_OBJECT_free(a->object);
        ASN1_OCTET_STRING_free(a->value);
        Free((char *)a);
index fc333e42c8ae844179e5cd7bc924ea4e43059881..1b0c8a0aa522f6012c45b586dc557c77f143f60d 100644 (file)
@@ -110,6 +110,7 @@ extern "C" {
 #define PEM_STRING_RSA         "RSA PRIVATE KEY"
 #define PEM_STRING_RSA_PUBLIC  "RSA PUBLIC KEY"
 #define PEM_STRING_DSA         "DSA PRIVATE KEY"
+#define PEM_STRING_DSA_PUBLIC  "DSA PUBLIC KEY"
 #define PEM_STRING_PKCS7       "PKCS7"
 #define PEM_STRING_PKCS8       "ENCRYPTED PRIVATE KEY"
 #define PEM_STRING_PKCS8INF    "PRIVATE KEY"
@@ -552,6 +553,8 @@ DECLARE_PEM_rw(RSAPublicKey, RSA)
 
 DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
 
+DECLARE_PEM_rw(DSAPublicKey, DSA)
+
 DECLARE_PEM_rw(DSAparams, DSA)
 
 #endif
index bc473f3cff4a457e1f1b526adf201f047e090489..b5857e0ebc9437505df033879b6bb4da09010fce 100644 (file)
@@ -92,6 +92,8 @@ IMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
 
 IMPLEMENT_PEM_rw_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
 
+IMPLEMENT_PEM_rw(DSAPublicKey, DSA, PEM_STRING_DSA_PUBLIC, DSAPublicKey)
+
 IMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
 
 #endif
index 262be3f9f25f02037cbbbc8478c47d87d5329218..17319fee11ec3d72e40d05642cf767e3135866a7 100644 (file)
@@ -176,9 +176,8 @@ typedef struct X509_extension_st
        short critical;
        short netscape_hack;
        ASN1_OCTET_STRING *value;
-       long argl;                      /* used when decoding */
-       char *argp;                     /* used when decoding */
-       void (*ex_free)();              /* clear argp stuff */
+       struct v3_ext_method *method;   /* V3 method to use */
+       void *ext_val;                  /* extension value */
        } X509_EXTENSION;
 
 DECLARE_STACK_OF(X509_EXTENSION)
@@ -583,6 +582,8 @@ RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
 int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
 #endif
 #ifndef NO_DSA
+DSA *d2i_DSAPublicKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPublicKey_fp(FILE *fp, DSA *dsa);
 DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
 int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
 X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
@@ -607,6 +608,8 @@ RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
 int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
 #endif
 #ifndef NO_DSA
+DSA *d2i_DSAPublicKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPublicKey_bio(BIO *bp, DSA *dsa);
 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
 int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
 #endif
index f2af895df00a644582428fae6a67f39e07712d82..354d4c3f3c18cad9b3bb3c4c836b5ec23d1b9732 100644 (file)
@@ -329,6 +329,18 @@ int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
        {
        return(ASN1_i2d_fp(i2d_DSAPrivateKey,fp,(unsigned char *)dsa));
        }
+
+DSA *d2i_DSAPublicKey_fp(FILE *fp, DSA **dsa)
+       {
+       return((DSA *)ASN1_d2i_fp((char *(*)())
+               DSA_new,(char *(*)())d2i_DSAPublicKey, (fp),
+               (unsigned char **)(dsa)));
+       }
+
+int i2d_DSAPublicKey_fp(FILE *fp, DSA *dsa)
+       {
+       return(ASN1_i2d_fp(i2d_DSAPublicKey,fp,(unsigned char *)dsa));
+       }
 #endif
 
 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
@@ -342,6 +354,19 @@ int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
        {
        return(ASN1_i2d_bio(i2d_DSAPrivateKey,bp,(unsigned char *)dsa));
        }
+
+DSA *d2i_DSAPublicKey_bio(BIO *bp, DSA **dsa)
+       {
+       return((DSA *)ASN1_d2i_bio((char *(*)())
+               DSA_new,(char *(*)())d2i_DSAPublicKey, (bp),
+               (unsigned char **)(dsa)));
+       }
+
+int i2d_DSAPublicKey_bio(BIO *bp, DSA *dsa)
+       {
+       return(ASN1_i2d_bio(i2d_DSAPublicKey,bp,(unsigned char *)dsa));
+       }
+
 #endif
 
 X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn)