Commit 7df1c720 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Fix typo in i2d_ASN1_ENUMERATED

Fix bug in read only memory BIOs so BIO_reset() works.

Add sign and verify options to dgst utility, need
to update docs.
parent b3756cf0
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -4,13 +4,17 @@

 Changes between 0.9.5a and 0.9.6  [xx XXX 2000]

  *) New options added to the 'dgst' utility for signature
     generation and verification.
     [Steve Henson]

  *) Unrecognized PKCS#7 content types are now handled via a
     catch all ASN1_TYPE structure. This allows unsupported
     types to be stored as a "blob" and an application can
     encode and decode it manually.
     [Steve Henson]

  *) Fix various signed/unsigned issues to make a_strex,c
  *) Fix various signed/unsigned issues to make a_strex.c
     compile under VC++.
     [Oscar Jacobsson <oscar.jacobsson@celocom.com>]

+174 −14
Original line number Diff line number Diff line
@@ -73,7 +73,8 @@
#undef PROG
#define PROG	dgst_main

void do_fp(unsigned char *buf,BIO *f,int sep);
void do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, char binout,
		EVP_PKEY *key, unsigned char *sigin, unsigned int siglen);

int MAIN(int, char **);

@@ -84,11 +85,18 @@ int MAIN(int argc, char **argv)
	const EVP_MD *md=NULL,*m;
	BIO *in=NULL,*inp;
	BIO *bmd=NULL;
	BIO *out = NULL;
	const char *name;
#define PROG_NAME_SIZE  16
	char pname[PROG_NAME_SIZE];
	int separator=0;
	int debug=0;
	const char *outfile = NULL, *keyfile = NULL;
	const char *sigfile = NULL, *randfile = NULL;
	char out_bin = -1, want_pub = 0, do_verify = 0;
	EVP_PKEY *sigkey = NULL;
	unsigned char *sigbuf = NULL;
	unsigned int siglen = 0;

	apps_startup();

@@ -113,6 +121,43 @@ int MAIN(int argc, char **argv)
		if ((*argv)[0] != '-') break;
		if (strcmp(*argv,"-c") == 0)
			separator=1;
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) break;
			randfile=*(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) break;
			outfile=*(++argv);
			}
		else if (strcmp(*argv,"-sign") == 0)
			{
			if (--argc < 1) break;
			keyfile=*(++argv);
			}
		else if (strcmp(*argv,"-verify") == 0)
			{
			if (--argc < 1) break;
			keyfile=*(++argv);
			want_pub = 1;
			do_verify = 1;
			}
		else if (strcmp(*argv,"-prverify") == 0)
			{
			if (--argc < 1) break;
			keyfile=*(++argv);
			do_verify = 1;
			}
		else if (strcmp(*argv,"-signature") == 0)
			{
			if (--argc < 1) break;
			sigfile=*(++argv);
			}
		else if (strcmp(*argv,"-hex") == 0)
			out_bin = 0;
		else if (strcmp(*argv,"-binary") == 0)
			out_bin = 1;
		else if (strcmp(*argv,"-d") == 0)
			debug=1;
		else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
@@ -126,12 +171,26 @@ int MAIN(int argc, char **argv)
	if (md == NULL)
		md=EVP_md5();

	if(do_verify && !sigfile) {
		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
		err = 1; 
		goto end;
	}

	if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
		{
		BIO_printf(bio_err,"unknown option '%s'\n",*argv);
		BIO_printf(bio_err,"options are\n");
		BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
		BIO_printf(bio_err,"-d              to output debug info\n");
		BIO_printf(bio_err,"-hex            output as hex dump\n");
		BIO_printf(bio_err,"-binary         output in binary form\n");
		BIO_printf(bio_err,"-sign   file    sign digest using private key in file\n");
		BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
		BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
		BIO_printf(bio_err,"-signature file signature to verify\n");
		BIO_printf(bio_err,"-binary         output in binary form\n");

		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm (default)\n",
			LN_md5,LN_md5);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
@@ -165,6 +224,72 @@ int MAIN(int argc, char **argv)
		goto end;
		}

	if(out_bin == -1) {
		if(keyfile) out_bin = 1;
		else out_bin = 0;
	}

	if(randfile)
		app_RAND_load_file(randfile, bio_err, 0);

	if(outfile) {
		if(out_bin)
			out = BIO_new_file(outfile, "wb");
		else    out = BIO_new_file(outfile, "w");
	} else out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if(!out) {
		BIO_printf(bio_err, "Error opening output file %s\n", 
					outfile ? outfile : "(stdout)");
		ERR_print_errors(bio_err);
		goto end;
	}

	if(keyfile) {
		BIO *keybio;
		keybio = BIO_new_file(keyfile, "r");
		if(!keybio) {
			BIO_printf(bio_err, "Error opening key file %s\n",
								keyfile);
			ERR_print_errors(bio_err);
			goto end;
		}
		
		if(want_pub) 
			sigkey = PEM_read_bio_PUBKEY(keybio, NULL, NULL, NULL);
		else sigkey = PEM_read_bio_PrivateKey(keybio, NULL, NULL, NULL);
		BIO_free(keybio);
		if(!sigkey) {
			BIO_printf(bio_err, "Error reading key file %s\n",
								keyfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if(sigfile && sigkey) {
		BIO *sigbio;
		sigbio = BIO_new_file(sigfile, "rb");
		siglen = EVP_PKEY_size(sigkey);
		sigbuf = OPENSSL_malloc(siglen);
		if(!sigbio) {
			BIO_printf(bio_err, "Error opening signature file %s\n",
								sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
		siglen = BIO_read(sigbio, sigbuf, siglen);
		BIO_free(sigbio);
		if(siglen <= 0) {
			BIO_printf(bio_err, "Error reading signature file %s\n",
								sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}
		


	/* we use md as a filter, reading from 'in' */
	BIO_set_md(bmd,md);
	inp=BIO_push(bmd,in);
@@ -172,7 +297,7 @@ int MAIN(int argc, char **argv)
	if (argc == 0)
		{
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
		do_fp(buf,inp,separator);
		do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, siglen);
		}
	else
		{
@@ -185,8 +310,9 @@ int MAIN(int argc, char **argv)
				err++;
				continue;
				}
			printf("%s(%s)= ",name,argv[i]);
			do_fp(buf,inp,separator);
			if(!out_bin) BIO_printf(out, "%s(%s)= ",name,argv[i]);
			do_fp(out, buf,inp,separator, out_bin, sigkey, 
								sigbuf, siglen);
			(void)BIO_reset(bmd);
			}
		}
@@ -197,11 +323,15 @@ end:
		OPENSSL_free(buf);
		}
	if (in != NULL) BIO_free(in);
	BIO_free(out);
	EVP_PKEY_free(sigkey);
	if(sigbuf) OPENSSL_free(sigbuf);
	if (bmd != NULL) BIO_free(bmd);
	EXIT(err);
	}

void do_fp(unsigned char *buf, BIO *bp, int sep)
void do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, char binout,
			EVP_PKEY *key, unsigned char *sigin, unsigned int siglen)
	{
	int len;
	int i;
@@ -211,14 +341,44 @@ void do_fp(unsigned char *buf, BIO *bp, int sep)
		i=BIO_read(bp,(char *)buf,BUFSIZE);
		if (i <= 0) break;
		}
	if(sigin)
		{
		EVP_MD_CTX *ctx;
		BIO_get_md_ctx(bp, &ctx);
		i = EVP_VerifyFinal(ctx, sigin, siglen, key); 
		if(i > 0) BIO_printf(out, "Verified OK\n");
		else if(i == 0) BIO_printf(out, "Verification Failure\n");
		else
			{
			BIO_printf(bio_err, "Error Verifying Data\n");
			ERR_print_errors(bio_err);
			}
		return;
		}
	if(key)
		{
		EVP_MD_CTX *ctx;
		BIO_get_md_ctx(bp, &ctx);
		if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) 
			{
			BIO_printf(bio_err, "Error Signing Data\n");
			ERR_print_errors(bio_err);
			return;
			}
		}
	else
		len=BIO_gets(bp,(char *)buf,BUFSIZE);

	if(binout) BIO_write(out, buf, len);
	else 
		{
		for (i=0; i<len; i++)
			{
			if (sep && (i != 0))
			putc(':',stdout);
		printf("%02x",buf[i]);
				BIO_printf(out, ":");
			BIO_printf(out, "%02x",buf[i]);
			}
		BIO_printf(out, "\n");
		}
	printf("\n");
	}
+1 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **pp)
	len = i2c_ASN1_INTEGER(a, NULL);	
	ret=ASN1_object_size(0,len,V_ASN1_ENUMERATED);
	if(pp) {
		ASN1_put_object(pp,0,ret,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL);
		ASN1_put_object(pp,0,len,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL);
		i2c_ASN1_INTEGER(a, pp);	
	}
	return ret;
+1 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
			/* For read only case reset to the start again */
			if(b->flags & BIO_FLAGS_MEM_RDONLY) 
					bm->data -= bm->max - bm->length;
					bm->length = bm->max;
			else {
				memset(bm->data,0,bm->max);
				bm->length=0;