From 3ea23631d4d840429dbe026f50e8f46a5187054f Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 4 Oct 1999 21:17:47 +0000 Subject: [PATCH] Add support for public key input and output in rsa and dsa utilities with some 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 | 6 ++++++ apps/dsa.c | 36 +++++++++++++++++++++++------------- apps/rsa.c | 42 ++++++++++++++++++++++++++++++------------ crypto/asn1/x_exten.c | 9 --------- crypto/pem/pem.h | 3 +++ crypto/pem/pem_all.c | 2 ++ crypto/x509/x509.h | 9 ++++++--- crypto/x509/x_all.c | 25 +++++++++++++++++++++++++ 8 files changed, 95 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index a7339e67e1..4e9fef40c1 100644 --- 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. diff --git a/apps/dsa.c b/apps/dsa.c index fedecf2739..6117fc4b2d 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -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; } diff --git a/apps/rsa.c b/apps/rsa.c index dd58a179a5..0351cb7d22 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -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 diff --git a/crypto/asn1/x_exten.c b/crypto/asn1/x_exten.c index d5f9e1df9e..f5931f7623 100644 --- a/crypto/asn1/x_exten.c +++ b/crypto/asn1/x_exten.c @@ -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); diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h index fc333e42c8..1b0c8a0aa5 100644 --- a/crypto/pem/pem.h +++ b/crypto/pem/pem.h @@ -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 diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index bc473f3cff..b5857e0ebc 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -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 diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index 262be3f9f2..17319fee11 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -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 diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index f2af895df0..354d4c3f3c 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -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) -- GitLab