summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2000-08-30 16:14:29 +0000
committerDr. Stephen Henson <steve@openssl.org>2000-08-30 16:14:29 +0000
commit7df1c720f60ad3813cc88607c4520da031e41e88 (patch)
treec45d2b02b837f2b503807989a4889a4ce7c5a0ad
parentb3756cf0e9622a4bbda5e4c417248255ba9daaf2 (diff)
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.
-rw-r--r--CHANGES6
-rw-r--r--apps/dgst.c188
-rw-r--r--crypto/asn1/a_enum.c2
-rw-r--r--crypto/bio/bss_mem.c1
4 files changed, 181 insertions, 16 deletions
diff --git a/CHANGES b/CHANGES
index e0120ae153..9c3a1e3fd6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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>]
diff --git a/apps/dgst.c b/apps/dgst.c
index 5286dd01ea..a151fb8457 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -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,"-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",
@@ -149,7 +208,7 @@ int MAIN(int argc, char **argv)
err=1;
goto end;
}
-
+
in=BIO_new(BIO_s_file());
bmd=BIO_new(BIO_f_md());
if (debug)
@@ -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;
}
- len=BIO_gets(bp,(char *)buf,BUFSIZE);
+ 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);
- for (i=0; i<len; i++)
+ if(binout) BIO_write(out, buf, len);
+ else
{
- if (sep && (i != 0))
- putc(':',stdout);
- printf("%02x",buf[i]);
+ for (i=0; i<len; i++)
+ {
+ if (sep && (i != 0))
+ BIO_printf(out, ":");
+ BIO_printf(out, "%02x",buf[i]);
+ }
+ BIO_printf(out, "\n");
}
- printf("\n");
}
diff --git a/crypto/asn1/a_enum.c b/crypto/asn1/a_enum.c
index afd8e9ab37..1428d1df7a 100644
--- a/crypto/asn1/a_enum.c
+++ b/crypto/asn1/a_enum.c
@@ -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;
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index c4e557822e..4fa2cf15a4 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -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;