Fix some typose in the i2d/d2i functions that
authorDr. Stephen Henson <steve@openssl.org>
Mon, 10 Jul 2000 18:33:05 +0000 (18:33 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 10 Jul 2000 18:33:05 +0000 (18:33 +0000)
call the i2c/c2i (they were not using the
content length for the headers).

Fix ASN1 long form tag encoding. This never
worked but it was never tested since it is
only used for tags > 30.

New options to smime program to allow the
PKCS#7 format to be specified and the content
supplied externally.

CHANGES
apps/apps.c
apps/apps.h
apps/smime.c
crypto/asn1/a_bitstr.c
crypto/asn1/a_int.c
crypto/asn1/asn1_lib.c

diff --git a/CHANGES b/CHANGES
index f3a7021e2312e33a22c5a41e1c92ae95fd83e74e..3f8faa98569904ca8f8de7408a4d1656246175f8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,16 @@
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
+  *) New options to smime application. -inform and -outform
+     allow alternative formats for the S/MIME message including
+     PEM and DER. The -content option allows the content to be
+     specified separately. This should allow things like Netscape
+     form signing output easier to verify.
+     [Steve Henson]
+
+  *) Fix the ASN1 encoding of tags using the 'long form'.
+     [Steve Henson]
+
   *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT
      STRING types. These convert content octets to and from the
      underlying type. The actual tag and length octets are
index b3a39690509c3141581e2deaff417ebecd187e26..0781c4bf939e9def64fbc8b758c759aa7d6d0421 100644 (file)
@@ -164,6 +164,8 @@ int str2fmt(char *s)
                return(FORMAT_PEM);
        else if ((*s == 'N') || (*s == 'n'))
                return(FORMAT_NETSCAPE);
+       else if ((*s == 'S') || (*s == 's'))
+               return(FORMAT_SMIME);
        else if ((*s == '1')
                || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
                || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
index 6b89b797513c616e509aea960c745ab20595542c..df939e0f401715f65e3b3ee813cc0c503387cac7 100644 (file)
@@ -158,6 +158,7 @@ STACK_OF(X509) *load_certs(BIO *err, char *file, int format);
 #define FORMAT_PEM      3
 #define FORMAT_NETSCAPE 4
 #define FORMAT_PKCS12   5
+#define FORMAT_SMIME    6
 
 #define NETSCAPE_CERT_HDR      "certificate"
 
index bb8ecd7cf03de9e83f61aa6cde9c9ff87fe980e3..ebc0eb6af44c1c22842112a66d6183250d1d1e4e 100644 (file)
@@ -87,7 +87,7 @@ int MAIN(int argc, char **argv)
        char *inmode = "r", *outmode = "w";
        char *infile = NULL, *outfile = NULL;
        char *signerfile = NULL, *recipfile = NULL;
-       char *certfile = NULL, *keyfile = NULL;
+       char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
        EVP_CIPHER *cipher = NULL;
        PKCS7 *p7 = NULL;
        X509_STORE *store = NULL;
@@ -102,6 +102,7 @@ int MAIN(int argc, char **argv)
        char *passargin = NULL, *passin = NULL;
        char *inrand = NULL;
        int need_rand = 0;
+       int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
        args = argv + 1;
 
        ret = 1;
@@ -205,11 +206,26 @@ int MAIN(int argc, char **argv)
                                args++;
                                infile = *args;
                        } else badarg = 1;
+               } else if (!strcmp (*args, "-inform")) {
+                       if (args[1]) {
+                               args++;
+                               informat = str2fmt(*args);
+                       } else badarg = 1;
+               } else if (!strcmp (*args, "-outform")) {
+                       if (args[1]) {
+                               args++;
+                               outformat = str2fmt(*args);
+                       } else badarg = 1;
                } else if (!strcmp (*args, "-out")) {
                        if (args[1]) {
                                args++;
                                outfile = *args;
                        } else badarg = 1;
+               } else if (!strcmp (*args, "-content")) {
+                       if (args[1]) {
+                               args++;
+                               contfile = *args;
+                       } else badarg = 1;
                } else badarg = 1;
                args++;
        }
@@ -292,9 +308,12 @@ int MAIN(int argc, char **argv)
 
        if(operation != SMIME_SIGN) flags &= ~PKCS7_DETACHED;
 
-       if(flags & PKCS7_BINARY) {
-               if(operation & SMIME_OP) inmode = "rb";
-               else outmode = "rb";
+       if(operation & SMIME_OP) {
+               if(flags & PKCS7_BINARY) inmode = "rb";
+               if(outformat == FORMAT_ASN1) outmode = "wb";
+       } else {
+               if(flags & PKCS7_BINARY) outmode = "wb";
+               if(informat == FORMAT_ASN1) inmode = "rb";
        }
 
        if(operation == SMIME_ENCRYPT) {
@@ -383,10 +402,28 @@ int MAIN(int argc, char **argv)
                p7 = PKCS7_sign(signer, key, other, in, flags);
                BIO_reset(in);
        } else {
-               if(!(p7 = SMIME_read_PKCS7(in, &indata))) {
+               if(informat == FORMAT_SMIME) 
+                       p7 = SMIME_read_PKCS7(in, &indata);
+               else if(informat == FORMAT_PEM) 
+                       p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+               else if(informat == FORMAT_ASN1) 
+                       p7 = d2i_PKCS7_bio(in, NULL);
+               else {
+                       BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
+                       goto end;
+               }
+
+               if(!p7) {
                        BIO_printf(bio_err, "Error reading S/MIME message\n");
                        goto end;
                }
+               if(contfile) {
+                       BIO_free(indata);
+                       if(!(indata = BIO_new_file(contfile, "rb"))) {
+                               BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+                               goto end;
+                       }
+               }
        }
 
        if(!p7) {
@@ -422,7 +459,16 @@ int MAIN(int argc, char **argv)
                if(to) BIO_printf(out, "To: %s\n", to);
                if(from) BIO_printf(out, "From: %s\n", from);
                if(subject) BIO_printf(out, "Subject: %s\n", subject);
-               SMIME_write_PKCS7(out, p7, in, flags);
+               if(outformat == FORMAT_SMIME) 
+                       SMIME_write_PKCS7(out, p7, in, flags);
+               else if(outformat == FORMAT_PEM) 
+                       PEM_write_bio_PKCS7(out,p7);
+               else if(outformat == FORMAT_ASN1) 
+                       i2d_PKCS7_bio(out,p7);
+               else {
+                       BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
+                       goto end;
+               }
        }
        ret = 0;
 end:
index 35fe01d27e31fcbc4e9a10c613a1ce0c1cec42b4..c0501e1ea95c0d107f8110d6f5acdac7644b7edb 100644 (file)
@@ -75,7 +75,7 @@ int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
        len = i2c_ASN1_BIT_STRING(a, NULL);     
        ret=ASN1_object_size(0,len,V_ASN1_BIT_STRING);
        if(pp) {
-               ASN1_put_object(pp,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL);
+               ASN1_put_object(pp,0,len,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL);
                i2c_ASN1_BIT_STRING(a, pp);     
        }
        return ret;
index 721592bf1c7bc0c837e7bda33e57f456cdfce599..45927ffd6e6ec81f4b6323001046c1a20285f29e 100644 (file)
@@ -80,7 +80,7 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
        len = i2c_ASN1_INTEGER(a, NULL);        
        ret=ASN1_object_size(0,len,V_ASN1_INTEGER);
        if(pp) {
-               ASN1_put_object(pp,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL);
+               ASN1_put_object(pp,0,len,V_ASN1_INTEGER,V_ASN1_UNIVERSAL);
                i2c_ASN1_INTEGER(a, pp);        
        }
        return ret;
index 11f8654c36e4c56b7250827a36f23ab4896cb458..77447a5240959387c9a7dd634e5519a8b171798f 100644 (file)
@@ -181,7 +181,7 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
             int xclass)
        {
        unsigned char *p= *pp;
-       int i;
+       int i, ttag;
 
        i=(constructed)?V_ASN1_CONSTRUCTED:0;
        i|=(xclass&V_ASN1_PRIVATE);
@@ -190,12 +190,15 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
        else
                {
                *(p++)=i|V_ASN1_PRIMITIVE_TAG;
-               while (tag > 0x7f)
+               for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
+               ttag = i;
+               while(i-- > 0)
                        {
-                       *(p++)=(tag&0x7f)|0x80;
-                       tag>>=7;
+                       p[i] = tag & 0x7f;
+                       if(i != (ttag - 1)) p[i] |= 0x80;
+                       tag >>= 7;
                        }
-               *(p++)=(tag&0x7f);
+               p += ttag;
                }
        if ((constructed == 2) && (length == 0))
                *(p++)=0x80; /* der_put_length would output 0 instead */