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 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.
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;
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);
}
}
- 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;
}
}
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;
}
* -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)
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;
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)
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;
}
}
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)
{
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");
}
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;
}
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)
{
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
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)))
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);
}
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);
#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"
DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
+DECLARE_PEM_rw(DSAPublicKey, DSA)
+
DECLARE_PEM_rw(DSAparams, DSA)
#endif
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
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)
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);
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
{
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)
{
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)