version 1.18, 2022/11/11 17:07:39 |
version 1.19, 2023/03/06 14:32:06 |
|
|
char *subject; |
char *subject; |
char *to; |
char *to; |
X509_VERIFY_PARAM *vpm; |
X509_VERIFY_PARAM *vpm; |
} smime_config; |
} cfg; |
|
|
static const EVP_CIPHER * |
static const EVP_CIPHER * |
get_cipher_by_name(char *name) |
get_cipher_by_name(char *name) |
|
|
if (*name++ != '-') |
if (*name++ != '-') |
return (1); |
return (1); |
|
|
if ((smime_config.cipher = get_cipher_by_name(name)) == NULL) |
if ((cfg.cipher = get_cipher_by_name(name)) == NULL) |
if ((smime_config.cipher = EVP_get_cipherbyname(name)) == NULL) |
if ((cfg.cipher = EVP_get_cipherbyname(name)) == NULL) |
return (1); |
return (1); |
|
|
*argsused = 1; |
*argsused = 1; |
|
|
static int |
static int |
smime_opt_inkey(char *arg) |
smime_opt_inkey(char *arg) |
{ |
{ |
if (smime_config.keyfile == NULL) { |
if (cfg.keyfile == NULL) { |
smime_config.keyfile = arg; |
cfg.keyfile = arg; |
return (0); |
return (0); |
} |
} |
|
|
if (smime_config.signerfile == NULL) { |
if (cfg.signerfile == NULL) { |
BIO_puts(bio_err, "Illegal -inkey without -signer\n"); |
BIO_puts(bio_err, "Illegal -inkey without -signer\n"); |
return (1); |
return (1); |
} |
} |
|
|
if (smime_config.sksigners == NULL) { |
if (cfg.sksigners == NULL) { |
if ((smime_config.sksigners = sk_OPENSSL_STRING_new_null()) == NULL) |
if ((cfg.sksigners = sk_OPENSSL_STRING_new_null()) == NULL) |
return (1); |
return (1); |
} |
} |
if (!sk_OPENSSL_STRING_push(smime_config.sksigners, |
if (!sk_OPENSSL_STRING_push(cfg.sksigners, |
smime_config.signerfile)) |
cfg.signerfile)) |
return (1); |
return (1); |
|
|
smime_config.signerfile = NULL; |
cfg.signerfile = NULL; |
|
|
if (smime_config.skkeys == NULL) { |
if (cfg.skkeys == NULL) { |
if ((smime_config.skkeys = sk_OPENSSL_STRING_new_null()) == NULL) |
if ((cfg.skkeys = sk_OPENSSL_STRING_new_null()) == NULL) |
return (1); |
return (1); |
} |
} |
if (!sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile)) |
if (!sk_OPENSSL_STRING_push(cfg.skkeys, cfg.keyfile)) |
return (1); |
return (1); |
|
|
smime_config.keyfile = arg; |
cfg.keyfile = arg; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
smime_opt_md(char *arg) |
smime_opt_md(char *arg) |
{ |
{ |
if ((smime_config.sign_md = EVP_get_digestbyname(arg)) == NULL) { |
if ((cfg.sign_md = EVP_get_digestbyname(arg)) == NULL) { |
BIO_printf(bio_err, "Unknown digest %s\n", arg); |
BIO_printf(bio_err, "Unknown digest %s\n", arg); |
return (1); |
return (1); |
} |
} |
|
|
static int |
static int |
smime_opt_signer(char *arg) |
smime_opt_signer(char *arg) |
{ |
{ |
if (smime_config.signerfile == NULL) { |
if (cfg.signerfile == NULL) { |
smime_config.signerfile = arg; |
cfg.signerfile = arg; |
return (0); |
return (0); |
} |
} |
|
|
if (smime_config.sksigners == NULL) { |
if (cfg.sksigners == NULL) { |
if ((smime_config.sksigners = sk_OPENSSL_STRING_new_null()) == NULL) |
if ((cfg.sksigners = sk_OPENSSL_STRING_new_null()) == NULL) |
return (1); |
return (1); |
} |
} |
if (!sk_OPENSSL_STRING_push(smime_config.sksigners, |
if (!sk_OPENSSL_STRING_push(cfg.sksigners, |
smime_config.signerfile)) |
cfg.signerfile)) |
return (1); |
return (1); |
|
|
if (smime_config.keyfile == NULL) |
if (cfg.keyfile == NULL) |
smime_config.keyfile = smime_config.signerfile; |
cfg.keyfile = cfg.signerfile; |
|
|
if (smime_config.skkeys == NULL) { |
if (cfg.skkeys == NULL) { |
if ((smime_config.skkeys = sk_OPENSSL_STRING_new_null()) == NULL) |
if ((cfg.skkeys = sk_OPENSSL_STRING_new_null()) == NULL) |
return (1); |
return (1); |
} |
} |
if (!sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile)) |
if (!sk_OPENSSL_STRING_push(cfg.skkeys, cfg.keyfile)) |
return (1); |
return (1); |
|
|
smime_config.keyfile = NULL; |
cfg.keyfile = NULL; |
|
|
smime_config.signerfile = arg; |
cfg.signerfile = arg; |
return (0); |
return (0); |
} |
} |
|
|
|
|
int oargc = argc; |
int oargc = argc; |
int badarg = 0; |
int badarg = 0; |
|
|
if (!args_verify(&argv, &argc, &badarg, bio_err, &smime_config.vpm)) |
if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm)) |
return (1); |
return (1); |
if (badarg) |
if (badarg) |
return (1); |
return (1); |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Certificate Authority file", |
.desc = "Certificate Authority file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.CAfile, |
.opt.arg = &cfg.CAfile, |
}, |
}, |
{ |
{ |
.name = "CApath", |
.name = "CApath", |
.argname = "path", |
.argname = "path", |
.desc = "Certificate Authority path", |
.desc = "Certificate Authority path", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.CApath, |
.opt.arg = &cfg.CApath, |
}, |
}, |
{ |
{ |
.name = "binary", |
.name = "binary", |
.desc = "Do not translate message to text", |
.desc = "Do not translate message to text", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_BINARY, |
.value = PKCS7_BINARY, |
}, |
}, |
{ |
{ |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Other certificates file", |
.desc = "Other certificates file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.certfile, |
.opt.arg = &cfg.certfile, |
}, |
}, |
{ |
{ |
.name = "content", |
.name = "content", |
.argname = "file", |
.argname = "file", |
.desc = "Supply or override content for detached signature", |
.desc = "Supply or override content for detached signature", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.contfile, |
.opt.arg = &cfg.contfile, |
}, |
}, |
{ |
{ |
.name = "crlfeol", |
.name = "crlfeol", |
.desc = "Use CRLF as EOL termination instead of CR only", |
.desc = "Use CRLF as EOL termination instead of CR only", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_CRLFEOL, |
.value = PKCS7_CRLFEOL, |
}, |
}, |
{ |
{ |
.name = "decrypt", |
.name = "decrypt", |
.desc = "Decrypt encrypted message", |
.desc = "Decrypt encrypted message", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.operation, |
.opt.value = &cfg.operation, |
.value = SMIME_DECRYPT, |
.value = SMIME_DECRYPT, |
}, |
}, |
{ |
{ |
.name = "encrypt", |
.name = "encrypt", |
.desc = "Encrypt message", |
.desc = "Encrypt message", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.operation, |
.opt.value = &cfg.operation, |
.value = SMIME_ENCRYPT, |
.value = SMIME_ENCRYPT, |
}, |
}, |
{ |
{ |
|
|
.argname = "addr", |
.argname = "addr", |
.desc = "From address", |
.desc = "From address", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.from, |
.opt.arg = &cfg.from, |
}, |
}, |
{ |
{ |
.name = "in", |
.name = "in", |
.argname = "file", |
.argname = "file", |
.desc = "Input file", |
.desc = "Input file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.infile, |
.opt.arg = &cfg.infile, |
}, |
}, |
{ |
{ |
.name = "indef", |
.name = "indef", |
.desc = "Same as -stream", |
.desc = "Same as -stream", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.indef, |
.opt.value = &cfg.indef, |
.value = 1, |
.value = 1, |
}, |
}, |
{ |
{ |
|
|
.argname = "fmt", |
.argname = "fmt", |
.desc = "Input format (DER, PEM or SMIME (default))", |
.desc = "Input format (DER, PEM or SMIME (default))", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &smime_config.informat, |
.opt.value = &cfg.informat, |
}, |
}, |
{ |
{ |
.name = "inkey", |
.name = "inkey", |
|
|
.argname = "fmt", |
.argname = "fmt", |
.desc = "Input key format (DER or PEM (default))", |
.desc = "Input key format (DER or PEM (default))", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &smime_config.keyform, |
.opt.value = &cfg.keyform, |
}, |
}, |
{ |
{ |
.name = "md", |
.name = "md", |
|
|
.name = "noattr", |
.name = "noattr", |
.desc = "Do not include any signed attributes", |
.desc = "Do not include any signed attributes", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOATTR, |
.value = PKCS7_NOATTR, |
}, |
}, |
{ |
{ |
.name = "nocerts", |
.name = "nocerts", |
.desc = "Do not include signer's certificate when signing", |
.desc = "Do not include signer's certificate when signing", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOCERTS, |
.value = PKCS7_NOCERTS, |
}, |
}, |
{ |
{ |
.name = "nochain", |
.name = "nochain", |
.desc = "Do not chain verification of signer's certificates", |
.desc = "Do not chain verification of signer's certificates", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOCHAIN, |
.value = PKCS7_NOCHAIN, |
}, |
}, |
{ |
{ |
.name = "nodetach", |
.name = "nodetach", |
.desc = "Use opaque signing", |
.desc = "Use opaque signing", |
.type = OPTION_VALUE_AND, |
.type = OPTION_VALUE_AND, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = ~PKCS7_DETACHED, |
.value = ~PKCS7_DETACHED, |
}, |
}, |
{ |
{ |
.name = "noindef", |
.name = "noindef", |
.desc = "Disable streaming I/O", |
.desc = "Disable streaming I/O", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.indef, |
.opt.value = &cfg.indef, |
.value = 0, |
.value = 0, |
}, |
}, |
{ |
{ |
.name = "nointern", |
.name = "nointern", |
.desc = "Do not search certificates in message for signer", |
.desc = "Do not search certificates in message for signer", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOINTERN, |
.value = PKCS7_NOINTERN, |
}, |
}, |
{ |
{ |
.name = "nooldmime", |
.name = "nooldmime", |
.desc = "Output old S/MIME content type", |
.desc = "Output old S/MIME content type", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOOLDMIMETYPE, |
.value = PKCS7_NOOLDMIMETYPE, |
}, |
}, |
{ |
{ |
.name = "nosigs", |
.name = "nosigs", |
.desc = "Do not verify message signature", |
.desc = "Do not verify message signature", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOSIGS, |
.value = PKCS7_NOSIGS, |
}, |
}, |
{ |
{ |
.name = "nosmimecap", |
.name = "nosmimecap", |
.desc = "Omit the SMIMECapabilities attribute", |
.desc = "Omit the SMIMECapabilities attribute", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOSMIMECAP, |
.value = PKCS7_NOSMIMECAP, |
}, |
}, |
{ |
{ |
.name = "noverify", |
.name = "noverify", |
.desc = "Do not verify signer's certificate", |
.desc = "Do not verify signer's certificate", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_NOVERIFY, |
.value = PKCS7_NOVERIFY, |
}, |
}, |
{ |
{ |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Output file", |
.desc = "Output file", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.outfile, |
.opt.arg = &cfg.outfile, |
}, |
}, |
{ |
{ |
.name = "outform", |
.name = "outform", |
.argname = "fmt", |
.argname = "fmt", |
.desc = "Output format (DER, PEM or SMIME (default))", |
.desc = "Output format (DER, PEM or SMIME (default))", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &smime_config.outformat, |
.opt.value = &cfg.outformat, |
}, |
}, |
{ |
{ |
.name = "passin", |
.name = "passin", |
.argname = "src", |
.argname = "src", |
.desc = "Private key password source", |
.desc = "Private key password source", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.passargin, |
.opt.arg = &cfg.passargin, |
}, |
}, |
{ |
{ |
.name = "pk7out", |
.name = "pk7out", |
.desc = "Output PKCS#7 structure", |
.desc = "Output PKCS#7 structure", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.operation, |
.opt.value = &cfg.operation, |
.value = SMIME_PK7OUT, |
.value = SMIME_PK7OUT, |
}, |
}, |
{ |
{ |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Recipient certificate file for decryption", |
.desc = "Recipient certificate file for decryption", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.recipfile, |
.opt.arg = &cfg.recipfile, |
}, |
}, |
{ |
{ |
.name = "resign", |
.name = "resign", |
.desc = "Resign a signed message", |
.desc = "Resign a signed message", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.operation, |
.opt.value = &cfg.operation, |
.value = SMIME_RESIGN, |
.value = SMIME_RESIGN, |
}, |
}, |
{ |
{ |
.name = "sign", |
.name = "sign", |
.desc = "Sign message", |
.desc = "Sign message", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.operation, |
.opt.value = &cfg.operation, |
.value = SMIME_SIGN, |
.value = SMIME_SIGN, |
}, |
}, |
{ |
{ |
|
|
.name = "stream", |
.name = "stream", |
.desc = "Enable streaming I/O", |
.desc = "Enable streaming I/O", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.indef, |
.opt.value = &cfg.indef, |
.value = 1, |
.value = 1, |
}, |
}, |
{ |
{ |
|
|
.argname = "s", |
.argname = "s", |
.desc = "Subject", |
.desc = "Subject", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.subject, |
.opt.arg = &cfg.subject, |
}, |
}, |
{ |
{ |
.name = "text", |
.name = "text", |
.desc = "Include or delete text MIME headers", |
.desc = "Include or delete text MIME headers", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &smime_config.flags, |
.opt.value = &cfg.flags, |
.value = PKCS7_TEXT, |
.value = PKCS7_TEXT, |
}, |
}, |
{ |
{ |
|
|
.argname = "addr", |
.argname = "addr", |
.desc = "To address", |
.desc = "To address", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &smime_config.to, |
.opt.arg = &cfg.to, |
}, |
}, |
{ |
{ |
.name = "verify", |
.name = "verify", |
.desc = "Verify signed message", |
.desc = "Verify signed message", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &smime_config.operation, |
.opt.value = &cfg.operation, |
.value = SMIME_VERIFY, |
.value = SMIME_VERIFY, |
}, |
}, |
{ |
{ |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
memset(&smime_config, 0, sizeof(smime_config)); |
memset(&cfg, 0, sizeof(cfg)); |
smime_config.flags = PKCS7_DETACHED; |
cfg.flags = PKCS7_DETACHED; |
smime_config.informat = FORMAT_SMIME; |
cfg.informat = FORMAT_SMIME; |
smime_config.outformat = FORMAT_SMIME; |
cfg.outformat = FORMAT_SMIME; |
smime_config.keyform = FORMAT_PEM; |
cfg.keyform = FORMAT_PEM; |
if (options_parse(argc, argv, smime_options, NULL, &argsused) != 0) { |
if (options_parse(argc, argv, smime_options, NULL, &argsused) != 0) { |
goto argerr; |
goto argerr; |
} |
} |
args = argv + argsused; |
args = argv + argsused; |
ret = 1; |
ret = 1; |
|
|
if (!(smime_config.operation & SMIME_SIGNERS) && |
if (!(cfg.operation & SMIME_SIGNERS) && |
(smime_config.skkeys != NULL || smime_config.sksigners != NULL)) { |
(cfg.skkeys != NULL || cfg.sksigners != NULL)) { |
BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); |
BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); |
goto argerr; |
goto argerr; |
} |
} |
if (smime_config.operation & SMIME_SIGNERS) { |
if (cfg.operation & SMIME_SIGNERS) { |
/* Check to see if any final signer needs to be appended */ |
/* Check to see if any final signer needs to be appended */ |
if (smime_config.keyfile != NULL && |
if (cfg.keyfile != NULL && |
smime_config.signerfile == NULL) { |
cfg.signerfile == NULL) { |
BIO_puts(bio_err, "Illegal -inkey without -signer\n"); |
BIO_puts(bio_err, "Illegal -inkey without -signer\n"); |
goto argerr; |
goto argerr; |
} |
} |
if (smime_config.signerfile != NULL) { |
if (cfg.signerfile != NULL) { |
if (smime_config.sksigners == NULL) { |
if (cfg.sksigners == NULL) { |
if ((smime_config.sksigners = |
if ((cfg.sksigners = |
sk_OPENSSL_STRING_new_null()) == NULL) |
sk_OPENSSL_STRING_new_null()) == NULL) |
goto end; |
goto end; |
} |
} |
if (!sk_OPENSSL_STRING_push(smime_config.sksigners, |
if (!sk_OPENSSL_STRING_push(cfg.sksigners, |
smime_config.signerfile)) |
cfg.signerfile)) |
goto end; |
goto end; |
if (smime_config.skkeys == NULL) { |
if (cfg.skkeys == NULL) { |
if ((smime_config.skkeys = |
if ((cfg.skkeys = |
sk_OPENSSL_STRING_new_null()) == NULL) |
sk_OPENSSL_STRING_new_null()) == NULL) |
goto end; |
goto end; |
} |
} |
if (smime_config.keyfile == NULL) |
if (cfg.keyfile == NULL) |
smime_config.keyfile = smime_config.signerfile; |
cfg.keyfile = cfg.signerfile; |
if (!sk_OPENSSL_STRING_push(smime_config.skkeys, |
if (!sk_OPENSSL_STRING_push(cfg.skkeys, |
smime_config.keyfile)) |
cfg.keyfile)) |
goto end; |
goto end; |
} |
} |
if (smime_config.sksigners == NULL) { |
if (cfg.sksigners == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"No signer certificate specified\n"); |
"No signer certificate specified\n"); |
badarg = 1; |
badarg = 1; |
} |
} |
smime_config.signerfile = NULL; |
cfg.signerfile = NULL; |
smime_config.keyfile = NULL; |
cfg.keyfile = NULL; |
} else if (smime_config.operation == SMIME_DECRYPT) { |
} else if (cfg.operation == SMIME_DECRYPT) { |
if (smime_config.recipfile == NULL && |
if (cfg.recipfile == NULL && |
smime_config.keyfile == NULL) { |
cfg.keyfile == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"No recipient certificate or key specified\n"); |
"No recipient certificate or key specified\n"); |
badarg = 1; |
badarg = 1; |
} |
} |
} else if (smime_config.operation == SMIME_ENCRYPT) { |
} else if (cfg.operation == SMIME_ENCRYPT) { |
if (*args == NULL) { |
if (*args == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"No recipient(s) certificate(s) specified\n"); |
"No recipient(s) certificate(s) specified\n"); |
badarg = 1; |
badarg = 1; |
} |
} |
} else if (!smime_config.operation) { |
} else if (!cfg.operation) { |
badarg = 1; |
badarg = 1; |
} |
} |
|
|
|
|
goto end; |
goto end; |
} |
} |
|
|
if (!app_passwd(bio_err, smime_config.passargin, NULL, &passin, NULL)) { |
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) { |
BIO_printf(bio_err, "Error getting password\n"); |
BIO_printf(bio_err, "Error getting password\n"); |
goto end; |
goto end; |
} |
} |
ret = 2; |
ret = 2; |
|
|
if (!(smime_config.operation & SMIME_SIGNERS)) |
if (!(cfg.operation & SMIME_SIGNERS)) |
smime_config.flags &= ~PKCS7_DETACHED; |
cfg.flags &= ~PKCS7_DETACHED; |
|
|
if (smime_config.operation & SMIME_OP) { |
if (cfg.operation & SMIME_OP) { |
if (smime_config.outformat == FORMAT_ASN1) |
if (cfg.outformat == FORMAT_ASN1) |
outmode = "wb"; |
outmode = "wb"; |
} else { |
} else { |
if (smime_config.flags & PKCS7_BINARY) |
if (cfg.flags & PKCS7_BINARY) |
outmode = "wb"; |
outmode = "wb"; |
} |
} |
|
|
if (smime_config.operation & SMIME_IP) { |
if (cfg.operation & SMIME_IP) { |
if (smime_config.informat == FORMAT_ASN1) |
if (cfg.informat == FORMAT_ASN1) |
inmode = "rb"; |
inmode = "rb"; |
} else { |
} else { |
if (smime_config.flags & PKCS7_BINARY) |
if (cfg.flags & PKCS7_BINARY) |
inmode = "rb"; |
inmode = "rb"; |
} |
} |
|
|
if (smime_config.operation == SMIME_ENCRYPT) { |
if (cfg.operation == SMIME_ENCRYPT) { |
if (smime_config.cipher == NULL) { |
if (cfg.cipher == NULL) { |
#ifndef OPENSSL_NO_RC2 |
#ifndef OPENSSL_NO_RC2 |
smime_config.cipher = EVP_rc2_40_cbc(); |
cfg.cipher = EVP_rc2_40_cbc(); |
#else |
#else |
BIO_printf(bio_err, "No cipher selected\n"); |
BIO_printf(bio_err, "No cipher selected\n"); |
goto end; |
goto end; |
|
|
args++; |
args++; |
} |
} |
} |
} |
if (smime_config.certfile != NULL) { |
if (cfg.certfile != NULL) { |
if ((other = load_certs(bio_err, smime_config.certfile, |
if ((other = load_certs(bio_err, cfg.certfile, |
FORMAT_PEM, NULL, "certificate file")) == NULL) { |
FORMAT_PEM, NULL, "certificate file")) == NULL) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
if (smime_config.recipfile != NULL && |
if (cfg.recipfile != NULL && |
(smime_config.operation == SMIME_DECRYPT)) { |
(cfg.operation == SMIME_DECRYPT)) { |
if ((recip = load_cert(bio_err, smime_config.recipfile, |
if ((recip = load_cert(bio_err, cfg.recipfile, |
FORMAT_PEM, NULL, "recipient certificate file")) == NULL) { |
FORMAT_PEM, NULL, "recipient certificate file")) == NULL) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
if (smime_config.operation == SMIME_DECRYPT) { |
if (cfg.operation == SMIME_DECRYPT) { |
if (smime_config.keyfile == NULL) |
if (cfg.keyfile == NULL) |
smime_config.keyfile = smime_config.recipfile; |
cfg.keyfile = cfg.recipfile; |
} else if (smime_config.operation == SMIME_SIGN) { |
} else if (cfg.operation == SMIME_SIGN) { |
if (smime_config.keyfile == NULL) |
if (cfg.keyfile == NULL) |
smime_config.keyfile = smime_config.signerfile; |
cfg.keyfile = cfg.signerfile; |
} else { |
} else { |
smime_config.keyfile = NULL; |
cfg.keyfile = NULL; |
} |
} |
|
|
if (smime_config.keyfile != NULL) { |
if (cfg.keyfile != NULL) { |
key = load_key(bio_err, smime_config.keyfile, |
key = load_key(bio_err, cfg.keyfile, |
smime_config.keyform, 0, passin, "signing key file"); |
cfg.keyform, 0, passin, "signing key file"); |
if (key == NULL) |
if (key == NULL) |
goto end; |
goto end; |
} |
} |
if (smime_config.infile != NULL) { |
if (cfg.infile != NULL) { |
if ((in = BIO_new_file(smime_config.infile, inmode)) == NULL) { |
if ((in = BIO_new_file(cfg.infile, inmode)) == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"Can't open input file %s\n", smime_config.infile); |
"Can't open input file %s\n", cfg.infile); |
goto end; |
goto end; |
} |
} |
} else { |
} else { |
|
|
goto end; |
goto end; |
} |
} |
|
|
if (smime_config.operation & SMIME_IP) { |
if (cfg.operation & SMIME_IP) { |
if (smime_config.informat == FORMAT_SMIME) |
if (cfg.informat == FORMAT_SMIME) |
p7 = SMIME_read_PKCS7(in, &indata); |
p7 = SMIME_read_PKCS7(in, &indata); |
else if (smime_config.informat == FORMAT_PEM) |
else if (cfg.informat == FORMAT_PEM) |
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); |
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); |
else if (smime_config.informat == FORMAT_ASN1) |
else if (cfg.informat == FORMAT_ASN1) |
p7 = d2i_PKCS7_bio(in, NULL); |
p7 = d2i_PKCS7_bio(in, NULL); |
else { |
else { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
|
|
BIO_printf(bio_err, "Error reading S/MIME message\n"); |
BIO_printf(bio_err, "Error reading S/MIME message\n"); |
goto end; |
goto end; |
} |
} |
if (smime_config.contfile != NULL) { |
if (cfg.contfile != NULL) { |
BIO_free(indata); |
BIO_free(indata); |
if ((indata = BIO_new_file(smime_config.contfile, |
if ((indata = BIO_new_file(cfg.contfile, |
"rb")) == NULL) { |
"rb")) == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"Can't read content file %s\n", |
"Can't read content file %s\n", |
smime_config.contfile); |
cfg.contfile); |
goto end; |
goto end; |
} |
} |
} |
} |
} |
} |
if (smime_config.outfile != NULL) { |
if (cfg.outfile != NULL) { |
if ((out = BIO_new_file(smime_config.outfile, outmode)) == NULL) { |
if ((out = BIO_new_file(cfg.outfile, outmode)) == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"Can't open output file %s\n", |
"Can't open output file %s\n", |
smime_config.outfile); |
cfg.outfile); |
goto end; |
goto end; |
} |
} |
} else { |
} else { |
|
|
goto end; |
goto end; |
} |
} |
|
|
if (smime_config.operation == SMIME_VERIFY) { |
if (cfg.operation == SMIME_VERIFY) { |
if ((store = setup_verify(bio_err, smime_config.CAfile, |
if ((store = setup_verify(bio_err, cfg.CAfile, |
smime_config.CApath)) == NULL) |
cfg.CApath)) == NULL) |
goto end; |
goto end; |
X509_STORE_set_verify_cb(store, smime_cb); |
X509_STORE_set_verify_cb(store, smime_cb); |
if (smime_config.vpm != NULL) { |
if (cfg.vpm != NULL) { |
if (!X509_STORE_set1_param(store, smime_config.vpm)) |
if (!X509_STORE_set1_param(store, cfg.vpm)) |
goto end; |
goto end; |
} |
} |
} |
} |
ret = 3; |
ret = 3; |
|
|
if (smime_config.operation == SMIME_ENCRYPT) { |
if (cfg.operation == SMIME_ENCRYPT) { |
if (smime_config.indef) |
if (cfg.indef) |
smime_config.flags |= PKCS7_STREAM; |
cfg.flags |= PKCS7_STREAM; |
p7 = PKCS7_encrypt(encerts, in, smime_config.cipher, |
p7 = PKCS7_encrypt(encerts, in, cfg.cipher, |
smime_config.flags); |
cfg.flags); |
} else if (smime_config.operation & SMIME_SIGNERS) { |
} else if (cfg.operation & SMIME_SIGNERS) { |
int i; |
int i; |
/* |
/* |
* If detached data content we only enable streaming if |
* If detached data content we only enable streaming if |
* S/MIME output format. |
* S/MIME output format. |
*/ |
*/ |
if (smime_config.operation == SMIME_SIGN) { |
if (cfg.operation == SMIME_SIGN) { |
if (smime_config.flags & PKCS7_DETACHED) { |
if (cfg.flags & PKCS7_DETACHED) { |
if (smime_config.outformat == FORMAT_SMIME) |
if (cfg.outformat == FORMAT_SMIME) |
smime_config.flags |= PKCS7_STREAM; |
cfg.flags |= PKCS7_STREAM; |
} else if (smime_config.indef) { |
} else if (cfg.indef) { |
smime_config.flags |= PKCS7_STREAM; |
cfg.flags |= PKCS7_STREAM; |
} |
} |
smime_config.flags |= PKCS7_PARTIAL; |
cfg.flags |= PKCS7_PARTIAL; |
p7 = PKCS7_sign(NULL, NULL, other, in, |
p7 = PKCS7_sign(NULL, NULL, other, in, |
smime_config.flags); |
cfg.flags); |
if (p7 == NULL) |
if (p7 == NULL) |
goto end; |
goto end; |
} else { |
} else { |
smime_config.flags |= PKCS7_REUSE_DIGEST; |
cfg.flags |= PKCS7_REUSE_DIGEST; |
} |
} |
for (i = 0; i < sk_OPENSSL_STRING_num(smime_config.sksigners); i++) { |
for (i = 0; i < sk_OPENSSL_STRING_num(cfg.sksigners); i++) { |
smime_config.signerfile = |
cfg.signerfile = |
sk_OPENSSL_STRING_value(smime_config.sksigners, i); |
sk_OPENSSL_STRING_value(cfg.sksigners, i); |
smime_config.keyfile = |
cfg.keyfile = |
sk_OPENSSL_STRING_value(smime_config.skkeys, i); |
sk_OPENSSL_STRING_value(cfg.skkeys, i); |
signer = load_cert(bio_err, smime_config.signerfile, |
signer = load_cert(bio_err, cfg.signerfile, |
FORMAT_PEM, NULL, "signer certificate"); |
FORMAT_PEM, NULL, "signer certificate"); |
if (signer == NULL) |
if (signer == NULL) |
goto end; |
goto end; |
key = load_key(bio_err, smime_config.keyfile, |
key = load_key(bio_err, cfg.keyfile, |
smime_config.keyform, 0, passin, |
cfg.keyform, 0, passin, |
"signing key file"); |
"signing key file"); |
if (key == NULL) |
if (key == NULL) |
goto end; |
goto end; |
if (PKCS7_sign_add_signer(p7, signer, key, |
if (PKCS7_sign_add_signer(p7, signer, key, |
smime_config.sign_md, smime_config.flags) == NULL) |
cfg.sign_md, cfg.flags) == NULL) |
goto end; |
goto end; |
X509_free(signer); |
X509_free(signer); |
signer = NULL; |
signer = NULL; |
|
|
key = NULL; |
key = NULL; |
} |
} |
/* If not streaming or resigning finalize structure */ |
/* If not streaming or resigning finalize structure */ |
if ((smime_config.operation == SMIME_SIGN) && |
if ((cfg.operation == SMIME_SIGN) && |
!(smime_config.flags & PKCS7_STREAM)) { |
!(cfg.flags & PKCS7_STREAM)) { |
if (!PKCS7_final(p7, in, smime_config.flags)) |
if (!PKCS7_final(p7, in, cfg.flags)) |
goto end; |
goto end; |
} |
} |
} |
} |
|
|
} |
} |
ret = 4; |
ret = 4; |
|
|
if (smime_config.operation == SMIME_DECRYPT) { |
if (cfg.operation == SMIME_DECRYPT) { |
if (!PKCS7_decrypt(p7, key, recip, out, smime_config.flags)) { |
if (!PKCS7_decrypt(p7, key, recip, out, cfg.flags)) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"Error decrypting PKCS#7 structure\n"); |
"Error decrypting PKCS#7 structure\n"); |
goto end; |
goto end; |
} |
} |
} else if (smime_config.operation == SMIME_VERIFY) { |
} else if (cfg.operation == SMIME_VERIFY) { |
STACK_OF(X509) *signers; |
STACK_OF(X509) *signers; |
if (PKCS7_verify(p7, other, store, indata, out, |
if (PKCS7_verify(p7, other, store, indata, out, |
smime_config.flags)) { |
cfg.flags)) { |
BIO_printf(bio_err, "Verification successful\n"); |
BIO_printf(bio_err, "Verification successful\n"); |
} else { |
} else { |
BIO_printf(bio_err, "Verification failure\n"); |
BIO_printf(bio_err, "Verification failure\n"); |
goto end; |
goto end; |
} |
} |
if ((signers = PKCS7_get0_signers(p7, other, |
if ((signers = PKCS7_get0_signers(p7, other, |
smime_config.flags)) == NULL) |
cfg.flags)) == NULL) |
goto end; |
goto end; |
if (!save_certs(smime_config.signerfile, signers)) { |
if (!save_certs(cfg.signerfile, signers)) { |
BIO_printf(bio_err, "Error writing signers to %s\n", |
BIO_printf(bio_err, "Error writing signers to %s\n", |
smime_config.signerfile); |
cfg.signerfile); |
sk_X509_free(signers); |
sk_X509_free(signers); |
ret = 5; |
ret = 5; |
goto end; |
goto end; |
} |
} |
sk_X509_free(signers); |
sk_X509_free(signers); |
} else if (smime_config.operation == SMIME_PK7OUT) { |
} else if (cfg.operation == SMIME_PK7OUT) { |
PEM_write_bio_PKCS7(out, p7); |
PEM_write_bio_PKCS7(out, p7); |
} else { |
} else { |
if (smime_config.to != NULL) |
if (cfg.to != NULL) |
BIO_printf(out, "To: %s\n", smime_config.to); |
BIO_printf(out, "To: %s\n", cfg.to); |
if (smime_config.from != NULL) |
if (cfg.from != NULL) |
BIO_printf(out, "From: %s\n", smime_config.from); |
BIO_printf(out, "From: %s\n", cfg.from); |
if (smime_config.subject != NULL) |
if (cfg.subject != NULL) |
BIO_printf(out, "Subject: %s\n", smime_config.subject); |
BIO_printf(out, "Subject: %s\n", cfg.subject); |
if (smime_config.outformat == FORMAT_SMIME) { |
if (cfg.outformat == FORMAT_SMIME) { |
if (smime_config.operation == SMIME_RESIGN) { |
if (cfg.operation == SMIME_RESIGN) { |
if (!SMIME_write_PKCS7(out, p7, indata, |
if (!SMIME_write_PKCS7(out, p7, indata, |
smime_config.flags)) |
cfg.flags)) |
goto end; |
goto end; |
} else { |
} else { |
if (!SMIME_write_PKCS7(out, p7, in, |
if (!SMIME_write_PKCS7(out, p7, in, |
smime_config.flags)) |
cfg.flags)) |
goto end; |
goto end; |
} |
} |
} else if (smime_config.outformat == FORMAT_PEM) { |
} else if (cfg.outformat == FORMAT_PEM) { |
if (!PEM_write_bio_PKCS7_stream(out, p7, in, |
if (!PEM_write_bio_PKCS7_stream(out, p7, in, |
smime_config.flags)) |
cfg.flags)) |
goto end; |
goto end; |
} else if (smime_config.outformat == FORMAT_ASN1) { |
} else if (cfg.outformat == FORMAT_ASN1) { |
if (!i2d_PKCS7_bio_stream(out, p7, in, |
if (!i2d_PKCS7_bio_stream(out, p7, in, |
smime_config.flags)) |
cfg.flags)) |
goto end; |
goto end; |
} else { |
} else { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
|
|
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
sk_X509_pop_free(encerts, X509_free); |
sk_X509_pop_free(encerts, X509_free); |
sk_X509_pop_free(other, X509_free); |
sk_X509_pop_free(other, X509_free); |
X509_VERIFY_PARAM_free(smime_config.vpm); |
X509_VERIFY_PARAM_free(cfg.vpm); |
sk_OPENSSL_STRING_free(smime_config.sksigners); |
sk_OPENSSL_STRING_free(cfg.sksigners); |
sk_OPENSSL_STRING_free(smime_config.skkeys); |
sk_OPENSSL_STRING_free(cfg.skkeys); |
X509_STORE_free(store); |
X509_STORE_free(store); |
X509_free(cert); |
X509_free(cert); |
X509_free(recip); |
X509_free(recip); |