/*
- * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Nokia 2007-2019
* Copyright Siemens AG 2015-2019
*
DEFINE_STACK_OF(X509_EXTENSION)
DEFINE_STACK_OF(OSSL_CMP_ITAV)
-/* start TODO remove when PR #11755 is merged */
-static char *get_passwd(const char *pass, const char *desc)
-{
- char *result = NULL;
-
- app_passwd(pass, NULL, &result, NULL);
- return result;
-}
-
-static void cleanse(char *str)
-{
- if (str != NULL)
- OPENSSL_cleanse(str, strlen(str));
-}
-
-static void clear_free(char *str)
-{
- if (str != NULL)
- OPENSSL_clear_free(str, strlen(str));
-}
-
-static int load_key_cert_crl(const char *uri, int maybe_stdin,
- const char *pass, const char *desc,
- EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl)
-{
- PW_CB_DATA uidata;
- OSSL_STORE_CTX *ctx = NULL;
- int ret = 0;
-
- if (ppkey != NULL)
- *ppkey = NULL;
- if (pcert != NULL)
- *pcert = NULL;
- if (pcrl != NULL)
- *pcrl = NULL;
-
- uidata.password = pass;
- uidata.prompt_info = uri;
-
- ctx = OSSL_STORE_open(uri, get_ui_method(), &uidata, NULL, NULL);
- if (ctx == NULL) {
- BIO_printf(bio_err, "Could not open file or uri %s for loading %s\n",
- uri, desc);
- goto end;
- }
-
- for (;;) {
- OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
- int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info);
- const char *infostr =
- info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
- int err = 0;
-
- if (info == NULL) {
- if (OSSL_STORE_eof(ctx))
- ret = 1;
- break;
- }
-
- switch (type) {
- case OSSL_STORE_INFO_PKEY:
- if (ppkey != NULL && *ppkey == NULL)
- err = ((*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) == NULL);
- break;
- case OSSL_STORE_INFO_CERT:
- if (pcert != NULL && *pcert == NULL)
- err = ((*pcert = OSSL_STORE_INFO_get1_CERT(info)) == NULL);
- break;
- case OSSL_STORE_INFO_CRL:
- if (pcrl != NULL && *pcrl == NULL)
- err = ((*pcrl = OSSL_STORE_INFO_get1_CRL(info)) == NULL);
- break;
- default:
- /* skip any other type */
- break;
- }
- OSSL_STORE_INFO_free(info);
- if (err) {
- BIO_printf(bio_err, "Could not read %s of %s from %s\n",
- infostr, desc, uri);
- break;
- }
- }
-
- end:
- if (ctx != NULL)
- OSSL_STORE_close(ctx);
- if (!ret)
- ERR_print_errors(bio_err);
- return ret;
-}
-
-static
-EVP_PKEY *load_key_preliminary(const char *uri, int format, int may_stdin,
- const char *pass, ENGINE *e, const char *desc)
-{
- EVP_PKEY *pkey = NULL;
-
- if (desc == NULL)
- desc = "private key";
-
- if (format == FORMAT_ENGINE) {
- if (e == NULL) {
- BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
- } else {
-#ifndef OPENSSL_NO_ENGINE
- PW_CB_DATA cb_data;
-
- cb_data.password = pass;
- cb_data.prompt_info = uri;
- if (ENGINE_init(e)) {
- pkey = ENGINE_load_private_key(e, uri,
- (UI_METHOD *)get_ui_method(),
- &cb_data);
- ENGINE_finish(e);
- }
- if (pkey == NULL) {
- BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
- ERR_print_errors(bio_err);
- }
-#else
- BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
-#endif
- }
- } else {
- (void)load_key_cert_crl(uri, may_stdin, pass, desc, &pkey, NULL, NULL);
- }
-
- if (pkey == NULL) {
- BIO_printf(bio_err, "Unable to load %s\n", desc);
- ERR_print_errors(bio_err);
- }
- return pkey;
-}
-
-static X509 *load_cert_pass(const char *uri, int maybe_stdin,
- const char *pass, const char *desc)
-{
- X509 *cert = NULL;
-
- if (desc == NULL)
- desc = "certificate";
- (void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL);
- if (cert == NULL) {
- BIO_printf(bio_err, "Unable to load %s\n", desc);
- ERR_print_errors(bio_err);
- }
- return cert;
-}
-/* end TODO remove when PR #11755 is merged */
-
static char *opt_config = NULL;
#define CMP_SECTION "cmp"
#define SECTION_NAME_MAX 40 /* max length of section name */
static CONF *conf = NULL; /* OpenSSL config file context structure */
static OSSL_CMP_CTX *cmp_ctx = NULL; /* the client-side CMP context */
-/* TODO remove when new setup_engine_flags() is in apps/lib/apps.c (PR #4277) */
-static
-ENGINE *setup_engine_flags(const char *engine, unsigned int flags, int debug)
-{
- return setup_engine(engine, debug);
-}
-
/* the type of cmp command we want to send */
typedef enum {
CMP_IR,
OPT_SECTION("Server authentication"),
{"trusted", OPT_TRUSTED, 's',
- "Trusted certs used for CMP server authentication when verifying responses"},
+ "Certificates to trust as chain roots when verifying signed CMP responses"},
{OPT_MORE_STR, 0, 0, "unless -srvcert is given"},
{"untrusted", OPT_UNTRUSTED, 's',
- "Intermediate certs for chain construction verifying CMP/TLS/enrolled certs"},
+ "Intermediate CA certs for chain construction for CMP/TLS/enrolled certs"},
{"srvcert", OPT_SRVCERT, 's',
- "Specific CMP server cert to use and trust directly when verifying responses"},
+ "Server cert to pin and trust directly when verifying signed CMP responses"},
{"recipient", OPT_RECIPIENT, 's',
- "Distinguished Name (DN) of the recipient to use unless -srvcert is given"},
+ "Distinguished Name (DN) to use as msg recipient; see man page for defaults"},
{"expect_sender", OPT_EXPECT_SENDER, 's',
- "DN of expected response sender. Defaults to DN of -srvcert, if provided"},
+ "DN of expected sender of responses. Defaults to subject of -srvcert, if any"},
{"ignore_keyusage", OPT_IGNORE_KEYUSAGE, '-',
"Ignore CMP signer cert key usage, else 'digitalSignature' must be allowed"},
{"unprotected_errors", OPT_UNPROTECTED_ERRORS, '-',
const char *pass, ENGINE *e, const char *desc)
{
char *pass_string = get_passwd(pass, desc);
- EVP_PKEY *pkey = load_key_preliminary(uri, format, 0, pass_string, e, desc);
+ EVP_PKEY *pkey = load_key(uri, format, 0, pass_string, e, desc);
clear_free(pass_string);
return pkey;
/*
* Any further certs and any untrusted certs are used for constructing
- * the client cert chain to be provided along with the TLS client cert
- * to the TLS server.
+ * the chain to be provided with the TLS client cert to the TLS server.
*/
if (!SSL_CTX_set0_chain(ssl_ctx, certs)) {
CMP_err("could not set TLS client cert chain");
}
}
- if (opt_days > 0)
- (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_VALIDITY_DAYS,
- opt_days);
+ if (opt_days > 0
+ && !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_VALIDITY_DAYS,
+ opt_days)) {
+ CMP_err("could to set requested cert validity period");
+ goto err;
+ }
if (opt_policies != NULL && opt_policy_oids != NULL) {
CMP_err("cannot have policies both via -policies and via -policy_oids");
goto oom;
if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy))
goto oom;
+ if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy))
+ goto oom;
(void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s%s%s/%s",
opt_tls_used ? "s" : "", opt_server,
server_port == 0 ? "" : ":", server_port_s,
+ opt_path == NULL ? "" :
opt_path[0] == '/' ? opt_path + 1 : opt_path);
if (opt_proxy != NULL)
if (!set_name(opt_recipient, OSSL_CMP_CTX_set1_recipient, ctx, "recipient")
|| !set_name(opt_expect_sender, OSSL_CMP_CTX_set1_expected_sender,
ctx, "expected sender"))
- goto oom;
+ goto err;
if (opt_geninfo != NULL && !handle_opt_geninfo(ctx))
goto err;
}
if (opt_engine != NULL)
- e = setup_engine_flags(opt_engine, 0 /* not: ENGINE_METHOD_ALL */, 0);
+ e = setup_engine_methods(opt_engine, 0 /* not: ENGINE_METHOD_ALL */, 0);
if (opt_port != NULL) {
if (opt_use_mock_srv) {
if ((acbio = http_server_init_bio(prog, opt_port)) == NULL)
goto err;
while (opt_max_msgs <= 0 || msgs < opt_max_msgs) {
+ char *path = NULL;
OSSL_CMP_MSG *req = NULL;
OSSL_CMP_MSG *resp = NULL;
ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG),
- (ASN1_VALUE **)&req, &cbio, acbio,
- prog, 0, 0);
+ (ASN1_VALUE **)&req, &path,
+ &cbio, acbio, prog, 0, 0);
if (ret == 0)
continue;
if (ret++ == -1)
ret = 0;
msgs++;
if (req != NULL) {
+ if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) {
+ (void)http_server_send_status(cbio, 404, "Not Found");
+ CMP_err1("Expecting empty path or 'pkix/' but got '%s'",
+ path);
+ OPENSSL_free(path);
+ OSSL_CMP_MSG_free(req);
+ goto cont;
+ }
+ OPENSSL_free(path);
resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req);
OSSL_CMP_MSG_free(req);
- if (resp == NULL)
+ if (resp == NULL) {
+ (void)http_server_send_status(cbio,
+ 500, "Internal Server Error");
break; /* treated as fatal error */
+ }
ret = http_server_send_asn1_resp(cbio, "application/pkixcmp",
ASN1_ITEM_rptr(OSSL_CMP_MSG),
(const ASN1_VALUE *)resp);
OSSL_CMP_MSG_free(resp);
if (!ret)
break; /* treated as fatal error */
+ } else {
+ (void)http_server_send_status(cbio, 400, "Bad Request");
}
+ cont:
BIO_free_all(cbio);
cbio = NULL;
}