Add support for CMS structure printing in cms utility.
[openssl.git] / apps / cms.c
index 29e43999e22d8da8906b2090522fa965186656b0..9607ec59207292de6a314986d24647e9f9ab5f0a 100644 (file)
@@ -110,21 +110,22 @@ int MAIN(int argc, char **argv)
        STACK_OF(X509) *encerts = NULL, *other = NULL;
        BIO *in = NULL, *out = NULL, *indata = NULL;
        int badarg = 0;
-       int flags = CMS_DETACHED;
+       int flags = CMS_DETACHED, noout = 0, print = 0;
        char *to = NULL, *from = NULL, *subject = NULL;
        char *CAfile = NULL, *CApath = NULL;
        char *passargin = NULL, *passin = NULL;
        char *inrand = NULL;
        int need_rand = 0;
-       int indef = 0;
        const EVP_MD *sign_md = NULL;
        int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
         int keyform = FORMAT_PEM;
 #ifndef OPENSSL_NO_ENGINE
        char *engine=NULL;
 #endif
-       unsigned char *secret_key = NULL;
-       size_t secret_keylen;
+       unsigned char *secret_key = NULL, *secret_keyid = NULL;
+       size_t secret_keylen = 0, secret_keyidlen = 0;
+
+       ASN1_OBJECT *econtent_type = NULL;
 
        X509_VERIFY_PARAM *vpm = NULL;
 
@@ -232,15 +233,22 @@ int MAIN(int argc, char **argv)
                else if (!strcmp (*args, "-no_attr_verify"))
                                flags |= CMS_NO_ATTR_VERIFY;
                else if (!strcmp (*args, "-stream"))
-                               indef = 1;
+                               flags |= CMS_STREAM;
                else if (!strcmp (*args, "-indef"))
-                               indef = 1;
+                               flags |= CMS_STREAM;
                else if (!strcmp (*args, "-noindef"))
-                               indef = 0;
+                               flags &= ~CMS_STREAM;
                else if (!strcmp (*args, "-nooldmime"))
                                flags |= CMS_NOOLDMIMETYPE;
                else if (!strcmp (*args, "-crlfeol"))
                                flags |= CMS_CRLFEOL;
+               else if (!strcmp (*args, "-noout"))
+                               noout = 1;
+               else if (!strcmp (*args, "-print"))
+                               {
+                               noout = 1;
+                               print = 1;
+                               }
                else if (!strcmp(*args,"-secretkey"))
                        {
                        long ltmp;
@@ -255,6 +263,32 @@ int MAIN(int argc, char **argv)
                                }
                        secret_keylen = (size_t)ltmp;
                        }
+               else if (!strcmp(*args,"-secretkeyid"))
+                       {
+                       long ltmp;
+                       if (!args[1])
+                               goto argerr;
+                       args++;
+                       secret_keyid = string_to_hex(*args, &ltmp);
+                       if (!secret_keyid)
+                               {
+                               BIO_printf(bio_err, "Invalid id %s\n", *args);
+                               goto argerr;
+                               }
+                       secret_keyidlen = (size_t)ltmp;
+                       }
+               else if (!strcmp(*args,"-econtent_type"))
+                       {
+                       if (!args[1])
+                               goto argerr;
+                       args++;
+                       econtent_type = OBJ_txt2obj(*args, 0);
+                       if (!econtent_type)
+                               {
+                               BIO_printf(bio_err, "Invalid OID %s\n", *args);
+                               goto argerr;
+                               }
+                       }
                else if (!strcmp(*args,"-rand"))
                        {
                        if (!args[1])
@@ -452,7 +486,7 @@ int MAIN(int argc, char **argv)
                }
        else if (operation == SMIME_DECRYPT)
                {
-               if (!recipfile && !keyfile)
+               if (!recipfile && !keyfile && !secret_key)
                        {
                        BIO_printf(bio_err, "No recipient certificate or key specified\n");
                        badarg = 1;
@@ -460,7 +494,7 @@ int MAIN(int argc, char **argv)
                }
        else if (operation == SMIME_ENCRYPT)
                {
-               if (!*args)
+               if (!*args && !secret_key)
                        {
                        BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
                        badarg = 1;
@@ -586,24 +620,27 @@ int MAIN(int argc, char **argv)
                {
                if (!cipher)
                        {
-#ifndef OPENSSL_NO_RC2                 
-                       cipher = EVP_rc2_40_cbc();
+#ifndef OPENSSL_NO_DES                 
+                       cipher = EVP_des_ede3_cbc();
 #else
                        BIO_printf(bio_err, "No cipher selected\n");
                        goto end;
 #endif
                        }
-               encerts = sk_X509_new_null();
+
+               if (secret_key && !secret_keyid)
+                       {
+                       BIO_printf(bio_err, "No sectre key id\n");
+                       goto end;
+                       }
+
+               if (*args)
+                       encerts = sk_X509_new_null();
                while (*args)
                        {
                        if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
                                NULL, e, "recipient certificate file")))
-                               {
-#if 0                          /* An appropriate message is already printed */
-                               BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
-#endif
                                goto end;
-                               }
                        sk_X509_push(encerts, cert);
                        cert = NULL;
                        args++;
@@ -726,35 +763,45 @@ int MAIN(int argc, char **argv)
 
        if (operation == SMIME_DATA_CREATE)
                {
-               if (indef)
-                       flags |= CMS_STREAM;
                cms = CMS_data_create(in, flags);
                }
        else if (operation == SMIME_DIGEST_CREATE)
                {
-               if (indef)
-                       flags |= CMS_STREAM;
                cms = CMS_digest_create(in, sign_md, flags);
                }
        else if (operation == SMIME_COMPRESS)
                {
-               if (indef)
-                       flags |= CMS_STREAM;
                cms = CMS_compress(in, -1, flags);
                }
        else if (operation == SMIME_ENCRYPT)
                {
-               if (indef)
-                       flags |= CMS_STREAM;
+               flags |= CMS_PARTIAL;
                cms = CMS_encrypt(encerts, in, cipher, flags);
+               if (!cms)
+                       goto end;
+               if (secret_key)
+                       {
+                       if (!CMS_add0_recipient_key(cms, NID_undef, 
+                                               secret_key, secret_keylen,
+                                               secret_keyid, secret_keyidlen,
+                                               NULL, NULL, NULL))
+                               goto end;
+                       /* NULL these because call absorbs them */
+                       secret_key = NULL;
+                       secret_keyid = NULL;
+                       }
+               if (!(flags & CMS_STREAM))
+                       {
+                       if (!CMS_final(cms, in, flags))
+                               goto end;
+                       }
                }
        else if (operation == SMIME_ENCRYPTED_ENCRYPT)
                {
-               if (indef)
-                       flags |= CMS_STREAM;
                cms = CMS_EncryptedData_encrypt(in, cipher,
                                                secret_key, secret_keylen,
                                                flags);
+
                }
        else if (operation & SMIME_SIGNERS)
                {
@@ -766,13 +813,13 @@ int MAIN(int argc, char **argv)
                        {
                        if (flags & CMS_DETACHED)
                                {
-                               if (outformat == FORMAT_SMIME)
-                                       flags |= CMS_STREAM;
+                               if (outformat != FORMAT_SMIME)
+                                       flags &= ~CMS_STREAM;
                                }
-                       else if (indef)
-                               flags |= CMS_STREAM;
                        flags |= CMS_PARTIAL;
                        cms = CMS_sign(NULL, NULL, other, in, flags);
+                       if (econtent_type)
+                               CMS_set1_eContentType(cms, econtent_type);
                        if (!cms)
                                goto end;
                        }
@@ -814,7 +861,30 @@ int MAIN(int argc, char **argv)
        ret = 4;
        if (operation == SMIME_DECRYPT)
                {
-               if (!CMS_decrypt(cms, key, recip, out, flags))
+
+               if (secret_key)
+                       {
+                       if (!CMS_decrypt_set1_key(cms,
+                                               secret_key, secret_keylen,
+                                               secret_keyid, secret_keyidlen))
+                               {
+                               BIO_puts(bio_err,
+                                       "Error decrypting CMS using secret key\n");
+                               goto end;
+                               }
+                       }
+
+               if (key)
+                       {
+                       if (!CMS_decrypt_set1_pkey(cms, key, recip))
+                               {
+                               BIO_puts(bio_err,
+                                       "Error decrypting CMS using private key\n");
+                               goto end;
+                               }
+                       }
+
+               if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
                        {
                        BIO_printf(bio_err, "Error decrypting CMS structure\n");
                        goto end;
@@ -872,7 +942,12 @@ int MAIN(int argc, char **argv)
                }
        else
                {
-               if (outformat == FORMAT_SMIME) 
+               if (noout)
+                       {
+                       if (print)
+                               CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
+                       }
+               else if (outformat == FORMAT_SMIME)
                        {
                        if (to)
                                BIO_printf(out, "To: %s\n", to);
@@ -916,6 +991,10 @@ end:
                sk_free(skkeys);
        if (secret_key)
                OPENSSL_free(secret_key);
+       if (secret_keyid)
+               OPENSSL_free(secret_keyid);
+       if (econtent_type)
+               ASN1_OBJECT_free(econtent_type);
        X509_STORE_free(store);
        X509_free(cert);
        X509_free(recip);