提交 a6e7fcd1 编写于 作者: D Dr. Stephen Henson

Multiple signer support in smime application.

上级 76cf3fcb
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]
*) Tidy up PKCS#7 routines and add new functions to make it easier to
create PKCS7 structures containing multiple signers. Update smime
application to support multiple signers.
[Steve Henson]
*) New -macalg option to pkcs12 utility to allow setting of an alternative *) New -macalg option to pkcs12 utility to allow setting of an alternative
digest MAC. digest MAC.
[Steve Henson] [Steve Henson]
......
...@@ -90,6 +90,7 @@ int MAIN(int argc, char **argv) ...@@ -90,6 +90,7 @@ int MAIN(int argc, char **argv)
const char *inmode = "r", *outmode = "w"; const char *inmode = "r", *outmode = "w";
char *infile = NULL, *outfile = NULL; char *infile = NULL, *outfile = NULL;
char *signerfile = NULL, *recipfile = NULL; char *signerfile = NULL, *recipfile = NULL;
STACK *sksigners = NULL, *skkeys = NULL;
char *certfile = NULL, *keyfile = NULL, *contfile=NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
const EVP_CIPHER *cipher = NULL; const EVP_CIPHER *cipher = NULL;
PKCS7 *p7 = NULL; PKCS7 *p7 = NULL;
...@@ -229,6 +230,20 @@ int MAIN(int argc, char **argv) ...@@ -229,6 +230,20 @@ int MAIN(int argc, char **argv)
{ {
if (!args[1]) if (!args[1])
goto argerr; goto argerr;
/* If previous -signer argument add signer to list */
if (signerfile)
{
if (!sksigners)
sksigners = sk_new_null();
sk_push(sksigners, signerfile);
if (!keyfile)
keyfile = signerfile;
if (!skkeys)
skkeys = sk_new_null();
sk_push(skkeys, keyfile);
keyfile = NULL;
}
signerfile = *++args; signerfile = *++args;
} }
else if (!strcmp (*args, "-recip")) else if (!strcmp (*args, "-recip"))
...@@ -241,6 +256,22 @@ int MAIN(int argc, char **argv) ...@@ -241,6 +256,22 @@ int MAIN(int argc, char **argv)
{ {
if (!args[1]) if (!args[1])
goto argerr; goto argerr;
/* If previous -inkey arument add signer to list */
if (keyfile)
{
if (!signerfile)
{
BIO_puts(bio_err, "Illegal -inkey without -signer\n");
goto argerr;
}
if (!sksigners)
sksigners = sk_new_null();
sk_push(sksigners, signerfile);
signerfile = NULL;
if (!skkeys)
skkeys = sk_new_null();
sk_push(skkeys, keyfile);
}
keyfile = *++args; keyfile = *++args;
} }
else if (!strcmp (*args, "-keyform")) else if (!strcmp (*args, "-keyform"))
...@@ -304,14 +335,38 @@ int MAIN(int argc, char **argv) ...@@ -304,14 +335,38 @@ int MAIN(int argc, char **argv)
args++; args++;
} }
if ((operation != SMIME_SIGN) && (skkeys || sksigners))
{
BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
goto argerr;
}
if (operation == SMIME_SIGN) if (operation == SMIME_SIGN)
{ {
if (!signerfile) /* Check to see if any final signer needs to be appended */
if (keyfile && !signerfile)
{
BIO_puts(bio_err, "Illegal -inkey without -signer\n");
goto argerr;
}
if (signerfile)
{
if (!sksigners)
sksigners = sk_new_null();
sk_push(sksigners, signerfile);
if (!skkeys)
skkeys = sk_new_null();
if (!keyfile)
keyfile = signerfile;
sk_push(skkeys, keyfile);
}
if (!sksigners)
{ {
BIO_printf(bio_err, "No signer certificate specified\n"); BIO_printf(bio_err, "No signer certificate specified\n");
badarg = 1; badarg = 1;
} }
signerfile = NULL;
keyfile = NULL;
need_rand = 1; need_rand = 1;
} }
else if (operation == SMIME_DECRYPT) else if (operation == SMIME_DECRYPT)
...@@ -565,17 +620,44 @@ int MAIN(int argc, char **argv) ...@@ -565,17 +620,44 @@ int MAIN(int argc, char **argv)
p7 = PKCS7_encrypt(encerts, in, cipher, flags); p7 = PKCS7_encrypt(encerts, in, cipher, flags);
else if (operation == SMIME_SIGN) else if (operation == SMIME_SIGN)
{ {
int i;
/* If detached data and SMIME output enable partial /* If detached data and SMIME output enable partial
* signing. * signing.
*/ */
if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME))
flags |= PKCS7_STREAM; flags |= PKCS7_STREAM;
p7 = PKCS7_sign(signer, key, other, in, flags); flags |= PKCS7_PARTIAL;
/* Don't need to rewind for partial signing */ p7 = PKCS7_sign(NULL, NULL, other, in, flags);
if (!(flags & PKCS7_STREAM) && (BIO_reset(in) != 0)) for (i = 0; i < sk_num(sksigners); i++)
{
signerfile = sk_value(sksigners, i);
keyfile = sk_value(skkeys, i);
signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
e, "signer certificate");
if (!signer)
goto end;
key = load_key(bio_err, keyfile, keyform, 0, passin, e,
"signing key file");
if (!key)
goto end;
if (!PKCS7_sign_add_signer(p7, signer, key,
NULL, flags))
goto end;
X509_free(signer);
signer = NULL;
EVP_PKEY_free(key);
key = NULL;
}
/* If not streaming finalize structure */
if (!(flags & PKCS7_STREAM))
{ {
BIO_printf(bio_err, "Can't rewind input file\n"); if (!PKCS7_final(p7, in, flags))
goto end; goto end;
if (BIO_reset(in) != 0)
{
BIO_puts(bio_err, "Can't rewind input file\n");
goto end;
}
} }
} }
else else
...@@ -674,6 +756,10 @@ end: ...@@ -674,6 +756,10 @@ end:
sk_X509_pop_free(other, X509_free); sk_X509_pop_free(other, X509_free);
if (vpm) if (vpm)
X509_VERIFY_PARAM_free(vpm); X509_VERIFY_PARAM_free(vpm);
if (sksigners)
sk_free(sksigners);
if (skkeys)
sk_free(skkeys);
X509_STORE_free(store); X509_STORE_free(store);
X509_free(cert); X509_free(cert);
X509_free(recip); X509_free(recip);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册