Commit 52664f50 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Transparent support for PKCS#8 private keys in RSA/DSA.

New universal public key format.

Fix CRL+cert load problem in by_file.c

Make verify report errors when loading files or dirs
parent a716d727
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -4,6 +4,50 @@

 Changes between 0.9.4 and 0.9.5  [xx XXX 1999]

  *) Modify RSA and DSA PEM read routines to transparently handle
     PKCS#8 format private keys. New *_PUBKEY_* functions that handle
     public keys in a format compatible with certificate
     SubjectPublicKeyInfo structures. Unfortunately there were already
     functions called *_PublicKey_* which used various odd formats so
     these are retained for compatability: however the DSA variants were
     never in a public release so they have been deleted. Changed dsa/rsa
     utilities to handle the new format: note no releases ever handled public
     keys so we should be OK.

     The primary motivation for this change is to avoid the same fiasco
     that dogs private keys: there are several incompatible private key
     formats some of which are standard and some OpenSSL specific and
     require various evil hacks to allow partial transparent handling and
     even then it doesn't work with DER formats. Given the option anything
     other than PKCS#8 should be dumped: but the other formats have to
     stay in the name of compatability.

     With public keys and the benefit of hindsight one standard format 
     is used which works with EVP_PKEY, RSA or DSA structures: though
     it clearly returns an error if you try to read the wrong kind of key.

     Added a -pubkey option to the 'x509' utility to output the public key.
     Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*() and add
     EVP_PKEY_rset_*() functions that do the same as the EVP_PKEY_assign_*()
     except they up the reference count of the added key (they don't "swallow"
     the supplied key).
     [Steve Henson]

  *) Fixes to crypto/x509/by_file.c the code to read in certificates and
     CRLs would fail if the file contained no certificates or no CRLs:
     added a new function to read in both types and return the number
     read: this means that if none are read it will be an error. The
     DER versions of the certificate and CRL reader would always fail
     because it isn't possible to mix certificates and CRLs in DER format
     without choking one or the other routine. Changed this to just read
     a certificate: this is the best we can do. Also modified the code
     in apps/verify.c to take notice of return codes: it was previously
     attempting to read in certificates from NULL pointers and ignoring
     any errors: this is one reason why the cert and CRL reader seemed
     to work. It doesn't check return codes from the default certificate
     routines: these may well fail if the certificates aren't installed.
     [Steve Henson]

  *) Code to support otherName option in GeneralName.
     [Steve Henson]

+4 −4
Original line number Diff line number Diff line
@@ -232,10 +232,10 @@ bad:

	BIO_printf(bio_err,"read DSA key\n");
	if	(informat == FORMAT_ASN1) {
		if(pubin) dsa=d2i_DSAPublicKey_bio(in,NULL);
		if(pubin) dsa=d2i_DSA_PUBKEY_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);
		if(pubin) dsa=PEM_read_bio_DSA_PUBKEY(in,NULL, NULL, NULL);
		else {
			if(passin) dsa=PEM_read_bio_DSAPrivateKey(in,NULL,
								key_cb,passin);
@@ -282,11 +282,11 @@ bad:
	if (noout) goto end;
	BIO_printf(bio_err,"writing DSA key\n");
	if 	(outformat == FORMAT_ASN1) {
		if(pubin || pubout) i=i2d_DSAPublicKey_bio(out,dsa);
		if(pubin || pubout) i=i2d_DSA_PUBKEY_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);
			i=PEM_write_bio_DSA_PUBKEY(out,dsa);
		else {
			if(passout) i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,
							NULL,0,key_cb, passout);
+13 −8
Original line number Diff line number Diff line
@@ -220,6 +220,11 @@ bad:

	ERR_load_crypto_strings();

	if(check && pubin) {
		BIO_printf(bio_err, "Only private keys can be checked\n");
		goto end;
	}

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
@@ -239,9 +244,9 @@ bad:
			}
		}

	BIO_printf(bio_err,"read RSA private key\n");
	BIO_printf(bio_err,"read RSA key\n");
	if	(informat == FORMAT_ASN1) {
		if (pubin) rsa=d2i_RSAPublicKey_bio(in,NULL);
		if (pubin) rsa=d2i_RSA_PUBKEY_bio(in,NULL);
		else rsa=d2i_RSAPrivateKey_bio(in,NULL);
	}
#ifndef NO_RC4
@@ -272,7 +277,7 @@ bad:
		}
#endif
	else if (informat == FORMAT_PEM) {
		if(pubin) rsa=PEM_read_bio_RSAPublicKey(in,NULL,NULL,NULL);
		if(pubin) rsa=PEM_read_bio_RSA_PUBKEY(in,NULL,NULL,NULL);
		else {
			if(passin) rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
								key_cb,passin);
@@ -286,7 +291,7 @@ bad:
		}
	if (rsa == NULL)
		{
		BIO_printf(bio_err,"unable to load Key\n");
		BIO_printf(bio_err,"unable to load key\n");
		ERR_print_errors(bio_err);
		goto end;
		}
@@ -312,9 +317,9 @@ bad:

	if (modulus)
		{
		fprintf(stdout,"Modulus=");
		BIO_printf(out,"Modulus=");
		BN_print(out,rsa->n);
		fprintf(stdout,"\n");
		BIO_printf(out,"\n");
		}

	if (check)
@@ -351,7 +356,7 @@ bad:
		}
	BIO_printf(bio_err,"writing RSA key\n");
	if 	(outformat == FORMAT_ASN1) {
		if(pubout || pubin) i=i2d_RSAPublicKey_bio(out,rsa);
		if(pubout || pubin) i=i2d_RSA_PUBKEY_bio(out,rsa);
		else i=i2d_RSAPrivateKey_bio(out,rsa);
	}
#ifndef NO_RC4
@@ -375,7 +380,7 @@ bad:
#endif
	else if (outformat == FORMAT_PEM) {
		if(pubout || pubin)
		    i=PEM_write_bio_RSAPublicKey(out,rsa);
		    i=PEM_write_bio_RSA_PUBKEY(out,rsa);
		else {
			if(passout) i=PEM_write_bio_RSAPrivateKey(out,rsa,
						enc,NULL,0,key_cb,passout);
+16 −4
Original line number Diff line number Diff line
@@ -124,13 +124,25 @@ int MAIN(int argc, char **argv)

	lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
	if (lookup == NULL) abort();
	if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
		X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
	if (CAfile) {
		i=X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM);
		if(!i) {
			BIO_printf(bio_err, "Error loading file %s\n", CAfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
		
	lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
	if (lookup == NULL) abort();
	if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
		X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
	if (CApath) {
		i=X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM);
		if(!i) {
			BIO_printf(bio_err, "Error loading directory %s\n", CApath);
			ERR_print_errors(bio_err);
			goto end;
		}
	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);


	ERR_clear_error();
+19 −1
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ static char *x509_usage[]={
" -purpose        - print out certificate purposes\n",
" -dates          - both Before and After dates\n",
" -modulus        - print the RSA key modulus\n",
" -pubkey         - output the public key\n",
" -fingerprint    - print the certificate fingerprint\n",
" -alias          - output certificate alias\n",
" -noout          - no certificate output\n",
@@ -161,7 +162,7 @@ int MAIN(int argc, char **argv)
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0;
	int trustout=0,clrtrust=0,clrnotrust=0,aliasout=0;
	int C=0;
	int x509req=0,days=DEF_DAYS,modulus=0;
	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
	int pprint = 0;
	char **pp;
	X509_STORE *ctx=NULL;
@@ -324,6 +325,8 @@ int MAIN(int argc, char **argv)
			serial= ++num;
		else if (strcmp(*argv,"-modulus") == 0)
			modulus= ++num;
		else if (strcmp(*argv,"-pubkey") == 0)
			pubkey= ++num;
		else if (strcmp(*argv,"-x509toreq") == 0)
			x509req= ++num;
		else if (strcmp(*argv,"-text") == 0)
@@ -639,6 +642,21 @@ bad:
				BIO_printf(STDout,"\n");
				EVP_PKEY_free(pkey);
				}
			else
				if (pubkey == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Error getting public key\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				PEM_write_bio_PUBKEY(STDout, pkey);
				EVP_PKEY_free(pkey);
				}
			else
				if (C == i)
				{
Loading