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...
This commit is contained in:
		
							
								
								
									
										6
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								apps/dsa.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								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;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								apps/rsa.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user