Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
else {
BIO_printf(bio_err, "Verification failure\n");
goto end;
}
} else if (operation == SMIME_ENCRYPTED_DECRYPT) {
if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
indata, out, flags))
goto end;
} else if (operation == SMIME_VERIFY) {
if (CMS_verify(cms, other, store, indata, out, flags) > 0)
BIO_printf(bio_err, "Verification successful\n");
else {
BIO_printf(bio_err, "Verification failure\n");
if (verify_retcode)
ret = verify_err + 32;
goto end;
}
if (signerfile) {
STACK_OF(X509) *signers;
signers = CMS_get0_signers(cms);
if (!save_certs(signerfile, signers)) {
BIO_printf(bio_err,
"Error writing signers to %s\n", signerfile);
ret = 5;
goto end;
}
sk_X509_free(signers);
}
if (rr_print)
} else if (operation == SMIME_VERIFY_RECEIPT) {
if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
BIO_printf(bio_err, "Verification successful\n");
else {
BIO_printf(bio_err, "Verification failure\n");
goto end;
}
} else {
if (noout) {
if (print)
CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
} else if (outformat == FORMAT_SMIME) {
if (to)
BIO_printf(out, "To: %s%s", to, mime_eol);
BIO_printf(out, "From: %s%s", from, mime_eol);
BIO_printf(out, "Subject: %s%s", subject, mime_eol);
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
if (operation == SMIME_RESIGN)
ret = SMIME_write_CMS(out, cms, indata, flags);
else
ret = SMIME_write_CMS(out, cms, in, flags);
} else if (outformat == FORMAT_PEM)
ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
else if (outformat == FORMAT_ASN1)
ret = i2d_CMS_bio_stream(out, cms, in, flags);
else {
BIO_printf(bio_err, "Bad output format for CMS file\n");
goto end;
}
if (ret <= 0) {
ret = 6;
goto end;
}
}
ret = 0;
end:
if (ret)
ERR_print_errors(bio_err);
if (need_rand)
sk_X509_pop_free(encerts, X509_free);
sk_X509_pop_free(other, X509_free);
sk_OPENSSL_STRING_free(sksigners);
sk_OPENSSL_STRING_free(skkeys);
OPENSSL_free(secret_key);
OPENSSL_free(secret_keyid);
OPENSSL_free(pwri_tmp);
CMS_ReceiptRequest_free(rr);
sk_OPENSSL_STRING_free(rr_to);
sk_OPENSSL_STRING_free(rr_from);
for (key_param = key_first; key_param;) {
cms_key_param *tparam;
sk_OPENSSL_STRING_free(key_param->param);
tparam = key_param->next;
OPENSSL_free(key_param);
key_param = tparam;
}
X509_STORE_free(store);
X509_free(cert);
X509_free(recip);
X509_free(signer);
EVP_PKEY_free(key);
CMS_ContentInfo_free(cms);
CMS_ContentInfo_free(rcms);
BIO_free(rctin);
BIO_free(in);
BIO_free(indata);
BIO_free_all(out);
}
static int save_certs(char *signerfile, STACK_OF(X509) *signers)
{
int i;
BIO *tmp;
if (!signerfile)
return 1;
tmp = BIO_new_file(signerfile, "w");
if (!tmp)
return 0;
for (i = 0; i < sk_X509_num(signers); i++)
PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
BIO_free(tmp);
return 1;
}
/* Minimal callback just to output policy info (if any) */
static int cms_cb(int ok, X509_STORE_CTX *ctx)
error = X509_STORE_CTX_get_error(ctx);
if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
&& ((error != X509_V_OK) || (ok != 2)))
return ok;
static void gnames_stack_print(STACK_OF(GENERAL_NAMES) *gns)
{
STACK_OF(GENERAL_NAME) *gens;
GENERAL_NAME *gen;
int i, j;
for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
gens = sk_GENERAL_NAMES_value(gns, i);
for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
gen = sk_GENERAL_NAME_value(gens, j);
BIO_puts(bio_err, " ");
GENERAL_NAME_print(bio_err, gen);
BIO_puts(bio_err, "\n");
static void receipt_request_print(CMS_ContentInfo *cms)
{
STACK_OF(CMS_SignerInfo) *sis;
CMS_SignerInfo *si;
CMS_ReceiptRequest *rr;
int allorfirst;
STACK_OF(GENERAL_NAMES) *rto, *rlist;
ASN1_STRING *scid;
int i, rv;
sis = CMS_get0_SignerInfos(cms);
for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
si = sk_CMS_SignerInfo_value(sis, i);
rv = CMS_get1_ReceiptRequest(si, &rr);
BIO_printf(bio_err, "Signer %d:\n", i + 1);
if (rv == 0)
BIO_puts(bio_err, " No Receipt Request\n");
else if (rv < 0) {
BIO_puts(bio_err, " Receipt Request Parse Error\n");
ERR_print_errors(bio_err);
} else {
const char *id;
int idlen;
CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
&rlist, &rto);
BIO_puts(bio_err, " Signed Content ID:\n");
idlen = ASN1_STRING_length(scid);
id = (const char *)ASN1_STRING_get0_data(scid);
BIO_dump_indent(bio_err, id, idlen, 4);
BIO_puts(bio_err, " Receipts From");
BIO_puts(bio_err, " List:\n");
gnames_stack_print(rlist);
BIO_printf(bio_err, " Unknown (%d)\n", allorfirst);
BIO_puts(bio_err, " Receipts To:\n");
gnames_stack_print(rto);
static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
{
int i;
STACK_OF(GENERAL_NAMES) *ret;
GENERAL_NAMES *gens = NULL;
GENERAL_NAME *gen = NULL;
ret = sk_GENERAL_NAMES_new_null();
if (!ret)
goto err;
for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
char *str = sk_OPENSSL_STRING_value(ns, i);
gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
if (!gen)
goto err;
gens = GENERAL_NAMES_new();
goto err;
if (!sk_GENERAL_NAME_push(gens, gen))
goto err;
gen = NULL;
if (!sk_GENERAL_NAMES_push(ret, gens))
goto err;
gens = NULL;
}
return ret;
err:
sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
GENERAL_NAMES_free(gens);
GENERAL_NAME_free(gen);
return NULL;
}
static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
*rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
*rr_from)
{
STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
CMS_ReceiptRequest *rr;
rct_to = make_names_stack(rr_to);
if (!rct_to)
goto err;
if (rr_from) {
rct_from = make_names_stack(rr_from);
if (!rct_from)
goto err;
} else
rct_from = NULL;
rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
rct_to);
return rr;
err:
sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
STACK_OF(OPENSSL_STRING) *param)
{
char *keyopt;
int i;
if (sk_OPENSSL_STRING_num(param) <= 0)
return 1;
for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
keyopt = sk_OPENSSL_STRING_value(param, i);
if (pkey_ctrl_string(pctx, keyopt) <= 0) {
BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
ERR_print_errors(bio_err);
return 0;
}
}
return 1;
}