diff --git a/CMakeLists.txt b/CMakeLists.txt index 576170ff..08788e01 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,18 @@ cmake_minimum_required(VERSION 3.18) project(libgencmp) set(LIBGENCMP_NAME gencmp) +include(ExternalProject) +ExternalProject_Add( +atg +GIT_REPOSITORY git@code.siemens.com:ct-rda-cst-ses-de/remote-attestation/base-functionality/attestation-token-generator +GIT_TAG ak/tcg-key-attestation-plugin +CONFIGURE_COMMAND "" +BUILD_COMMAND "" +INSTALL_COMMAND "" +TEST_COMMAND "" +SOURCE_DIR atg +) + if(NOT DEFINED GENCMPCLIENT_VERSION) set(GENCMPCLIENT_VERSION_MAJOR 2) set(GENCMPCLIENT_VERSION_MINOR 2) @@ -215,7 +227,7 @@ if(DEFINED USE_LIBCMP) endif() include_directories( - ${INC_DIR} + ${INC_DIR} ${PROJECT_SOURCE_DIR}/atg ) if(DEFINED USE_LIBCMP) include_directories(SYSTEM ${CMPOSSL_INC_DIR}/cmp) @@ -288,6 +300,7 @@ target_link_libraries(cmpClient # important: libcmp before libcrypto such that its contents are preferred OpenSSL::Crypto $<$>:OpenSSL::SSL> + ${PROJECT_SOURCE_DIR}/atg/atglib-key-attestation-demo/libatg.so ) if(DEFINED ENV{SECUTILS_USE_UTA}) target_link_libraries(cmpClient uta) diff --git a/doCrWithRat.sh b/doCrWithRat.sh new file mode 100755 index 00000000..dd26bec7 --- /dev/null +++ b/doCrWithRat.sh @@ -0,0 +1,15 @@ +cd ./test/recipes/80-test_cmp_http_data/Mock +# gdb --args \ +../../../../cmpClient \ + -config ../test.cnf \ + -section "Mock" -cmd cr \ + -rats \ + -tpmkd_tokenname "tcg-key-req" \ + -tpmkd_tokencfgpath "../../../../atg/atglib-key-attestation-demo/token-cfg.json" \ + -tpmkd_plugincfgpath "../../../../atg/atglib-key-attestation-demo/plugins.json" \ + -tpmkd_nonce test_nonce_1234 \ + -atcha_tokenname "tcg-key-chal" \ + -atcha_tokencfgpath "../../../../atg/atglib-key-attestation-demo/token-cfg.json" \ + -atcha_plugincfgpath "../../../../atg/atglib-key-attestation-demo/plugins.json" \ + -atcha_nonce test_nonce_5678 + diff --git a/env.sh b/env.sh new file mode 100644 index 00000000..18192d47 --- /dev/null +++ b/env.sh @@ -0,0 +1,4 @@ +export OPENSSL_DIR=~/git/openssl +export OPENSSL_LIB=~/git/openssl +export LD_LIBRARY_PATH=~/git/openssl/:~/git/gencmpclient +export PATH=~/git/openssl/apps:$PATH diff --git a/include/genericCMPClient.h b/include/genericCMPClient.h index 5b7d388c..f7500670 100644 --- a/include/genericCMPClient.h +++ b/include/genericCMPClient.h @@ -35,7 +35,6 @@ extern "C" { /* for low-level CMP API, in particular, type OSSL_CMP_CTX */ # include /* for abbreviation and backward compatibility: */ -typedef OSSL_CMP_CTX CMP_CTX; # if OPENSSL_VERSION_NUMBER < 0x30000080L # define OSSL_CMP_PKISTATUS_request -3 @@ -126,6 +125,16 @@ typedef int CMP_err; # include "genericCMPClient_util.h" # endif /* ndef GENCMP_NO_SECUTILS */ +#include "atglib-key-attestation-demo/libatg.h" + +typedef struct CMP_CTX { + OSSL_CMP_CTX *osslctx; + bool do_rats; + struct token_req tpm_kd_req; + struct token_req attest_chal; +} CMP_CTX; + + /* CMP client core functions */ /* should be called once, as soon as the application starts */ CMP_err CMPclient_init(OPTIONAL const char *name, OPTIONAL LOG_cb_t log_fn); @@ -216,10 +225,10 @@ CMP_err CMPclient_pkcs10(CMP_CTX *ctx, CREDENTIALS **new_creds, const X509_REQ *csr); CMP_err CMPclient_update(CMP_CTX *ctx, CREDENTIALS **new_creds, OPTIONAL const EVP_PKEY *new_key); -CMP_err CMPclient_update_anycert(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_update_anycert(CMP_CTX *ctx, CREDENTIALS **new_creds, OPTIONAL const X509 *old_cert, OPTIONAL const EVP_PKEY *new_key); -CMP_err CMPclient_update_with_exts(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_update_with_exts(CMP_CTX *ctx, CREDENTIALS **new_creds, OPTIONAL const X509 *old_cert, OPTIONAL const EVP_PKEY *new_key, OPTIONAL const X509_EXTENSIONS *exts); @@ -252,7 +261,7 @@ CMP_err CMPclient_crlUpdate(CMP_CTX *ctx, OPTIONAL const X509 *cert, # endif /* get error information sent by the server */ -char *CMPclient_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, +char *CMPclient_snprint_PKIStatus(const CMP_CTX *ctx, char *buf, size_t bufsize); /* must be called between any of the above certificate management activities */ diff --git a/runMock.sh b/runMock.sh new file mode 100755 index 00000000..50fceb9f --- /dev/null +++ b/runMock.sh @@ -0,0 +1,3 @@ +cd ~/git/gencmpclient/test/recipes/80-test_cmp_http_data/Mock +openssl cmp -config server.cnf + diff --git a/src/cmpClient.c b/src/cmpClient.c index ec342853..de13d454 100644 --- a/src/cmpClient.c +++ b/src/cmpClient.c @@ -31,6 +31,7 @@ #include /* for CERT{,S}_save and CERTS_free */ #include /* for UTIL_parse_name */ + #ifdef LOCAL_DEFS # include "genericCMPClient_use.h" #endif @@ -150,6 +151,10 @@ bool opt_implicit_confirm; bool opt_disable_confirm; const char *opt_certout; const char *opt_chainout; +bool opt_rats; + +struct token_req opt_tpm_kd_req; +struct token_req opt_attest_chal; /* certificate enrollment and revocation */ const char *opt_oldcert; @@ -286,6 +291,28 @@ opt_t cmp_opts[] = { "File to save newly enrolled certificate, possibly with chain and key"}, { "chainout", OPT_TXT, {.txt = NULL}, { &opt_chainout }, "File to save the chain of the newly enrolled certificate"}, + { "rats", OPT_BOOL, {.bit = false}, + { (const char **) &opt_rats }, + "Request certificate with remote attestation"}, + + { "tpmkd_tokenname", OPT_TXT, {.txt = NULL}, {(const char**) &opt_tpm_kd_req.token_name }, + "Token name for TPM key data request"}, + { "tpmkd_tokencfgpath", OPT_TXT, {.txt = NULL}, {(const char**) &opt_tpm_kd_req.config_path }, + "Path to the RATS token configuration file for TPM key data request"}, + { "tpmkd_plugincfgpath", OPT_TXT, {.txt = NULL}, {(const char**) &opt_tpm_kd_req.plugconf_path }, + "Path to the RATS plugin configuration file for TPM key data request"}, + { "tpmkd_nonce", OPT_TXT, {.txt = NULL}, {(const char**) &opt_tpm_kd_req.nonce }, + "Nonce for TPM key data request"}, + + { "atcha_tokenname", OPT_TXT, {.txt = NULL}, {(const char**) &opt_attest_chal.token_name }, + "Token name for attestation challenge"}, + { "atcha_tokencfgpath", OPT_TXT, {.txt = NULL}, {(const char**) &opt_attest_chal.config_path }, + "Path to the RATS token configuration file for attestation challenge"}, + { "atcha_plugincfgpath", OPT_TXT, {.txt = NULL}, {(const char**) &opt_attest_chal.plugconf_path }, + "Path to the RATS plugin configuration file for attestation challenge"}, + { "atcha_nonce", OPT_TXT, {.txt = NULL}, {(const char**) &opt_attest_chal.nonce }, + "Nonce for attestation challenge"}, + OPT_HEADER("Certificate enrollment and revocation"), { "oldcert", OPT_TXT, {.txt = NULL}, { &opt_oldcert }, @@ -510,7 +537,112 @@ static int SSL_CTX_add_extra_chain_free(SSL_CTX *ssl_ctx, STACK_OF(X509) *certs) } #endif -static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc) +#define EVIDENCE_LEN 2000 +#define NONCE_SZ 32 +static X509_EXTENSIONS *getattestationExt(CMP_CTX *ctx) +{ + X509_EXTENSIONS *exts = NULL; + X509_EXTENSION *ext = NULL; + unsigned char *der_data = NULL, *evidence = NULL; + int der_len = 0, ret = 0; + unsigned int atg_ret; + ASN1_OCTET_STRING oct; + struct token_resp resp; + ctx->attest_chal.nonce_size = ctx->attest_chal.nonce != NULL ? + strlen((const char*)opt_attest_chal.nonce) : 0; + ctx->attest_chal.user_data_size = 0; + atg_ret = atg_generate_evidence(ctx->attest_chal, &resp); + if (atg_ret == 0) { + printf("Token size: %lu\n", resp.token.buf_size); +#if 0 + printf("Token: [ "); + for (size_t i = 0; i < resp.token.buf_size; i++) + printf("0x%x ", resp.token.buf[i] & 0xff); + printf("]\n"); +#endif + if (resp.num_submods > 0) { + printf("Error: submodules are not supported."); + goto err; + } + oct.data = resp.token.buf; + oct.length = (int)resp.token.buf_size; + oct.flags = 0; + } else { + printf("An error has occurred in generating attestation token, return code - %d\n", atg_ret); + printf("Token request details:\n"); + printf("Token Name: %s\n", ctx->attest_chal.token_name); + printf("Config Path: %s\n", ctx->attest_chal.config_path); + printf("Plugin Config Path: %s\n", ctx->attest_chal.plugconf_path); + printf("\nNonce Size: %zu\n", ctx->attest_chal.nonce_size); + printf("Nonce: "); + for (size_t i = 0; i < ctx->attest_chal.nonce_size; i++) + printf("0x%x ", ctx->attest_chal.nonce[i] & 0xff); + printf("\nUser Data Size: %zu\n\n", ctx->attest_chal.user_data_size); + goto err; + } + +#ifdef TEST_DUMMY_EVIDENCE + int evidence_len = EVIDENCE_LEN; + /* TODO: get evidence from library */ + (void)ctx; + evidence = OPENSSL_malloc(EVIDENCE_LEN); + if (evidence == NULL) + return NULL; + memset(evidence, 0xAA, EVIDENCE_LEN); + oct.data = evidence; + oct.length = evidence_len; + oct.flags = 0; +#endif + + der_len = i2d_ASN1_OCTET_STRING(&oct, &der_data); + if (der_len < 0) + goto err; + + oct.data = der_data; + oct.length = der_len; + oct.flags = 0; + + // TODO find right OID + ASN1_OBJECT* evidenceStatement = OBJ_txt2obj ("1.2.3.4.5", 1); + if (evidenceStatement == NULL) + goto err; + + ext = X509_EXTENSION_create_by_OBJ(NULL, evidenceStatement, + 0, &oct); + if (ext == NULL + || (exts = sk_X509_EXTENSION_new_null()) == NULL + || !sk_X509_EXTENSION_push(exts, ext)) + goto err; + ret = 1; + + err: + OPENSSL_free(evidence); + OPENSSL_free(der_data); + if (atg_ret == 0) + atg_free_attestation_token(resp); + if (ret == 0) { + X509_EXTENSION_free(ext); + sk_X509_EXTENSION_free(exts); + exts = NULL; + } + return exts; +} + +static int add_rats_extensions(CMP_CTX *ctx, X509_EXTENSIONS **exts) +{ + int ret = 0; + X509_EXTENSIONS *rats_exts; + + if (exts == NULL) + return 0; + if ((rats_exts = getattestationExt(ctx)) != NULL) { + ret = X509v3_add_extensions(exts, rats_exts) != NULL; + sk_X509_EXTENSION_pop_free(rats_exts, X509_EXTENSION_free); + } + return ret; +} + +static int set_gennames(CMP_CTX *ctx, char *names, const char *desc) { char *next; GENERAL_NAME *n; @@ -519,7 +651,7 @@ static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc) next = UTIL_next_item(names); if (strcmp(names, "critical") == 0) { - (void)OSSL_CMP_CTX_set_option(ctx, + (void)OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL, 1); continue; @@ -539,7 +671,7 @@ static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc) LOG(FL_ERR, "Bad syntax of %s '%s'", desc, names); return 0; } - if (!OSSL_CMP_CTX_push1_subjectAltName(ctx, n)) { + if (!OSSL_CMP_CTX_push1_subjectAltName(ctx->osslctx, n)) { GENERAL_NAME_free(n); LOG_err("Out of memory"); return 0; @@ -704,7 +836,7 @@ static X509_EXTENSIONS *setup_X509_extensions(CMP_CTX *ctx) if (opt_policy_oids_critical) { if (opt_policy_oids == NULL) LOG_warn("-policy_oids_critical has no effect unless -policy_oids is given"); - if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POLICIES_CRITICAL, 1)) { + if (!OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_POLICIES_CRITICAL, 1)) { LOG_err("Failed to set 'setPoliciesCritical' field of CMP context"); goto err; } @@ -727,7 +859,7 @@ static X509_EXTENSIONS *setup_X509_extensions(CMP_CTX *ctx) } pinfo->policyid = policy; - if (!OSSL_CMP_CTX_push0_policy(ctx, pinfo)) { + if (!OSSL_CMP_CTX_push0_policy(ctx->osslctx, pinfo)) { LOG(FL_ERR, "Cannot add policy with OID '%s'", opt_policy_oids); POLICYINFO_free(pinfo); goto err; @@ -885,7 +1017,7 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx, static int set_name(OPTIONAL const char *str, int (*set_fn) (OSSL_CMP_CTX *ctx, const X509_NAME *name), - OSSL_CMP_CTX *ctx, const char *desc) + CMP_CTX *ctx, const char *desc) { if (str != NULL) { X509_NAME *n = UTIL_parse_name(str, MBSTRING_UTF8, false); @@ -894,7 +1026,7 @@ static int set_name(OPTIONAL const char *str, LOG(FL_ERR, "Cannot parse %s DN '%s'", desc, str); return -03; } - if (!(*set_fn) (ctx, n)) { + if (!(*set_fn) (ctx->osslctx, n)) { X509_NAME_free(n); LOG_err("Out of memory"); return -04; @@ -915,7 +1047,7 @@ static int setup_cert_template(CMP_CTX *ctx) if (opt_san_nodefault) { if (opt_sans != NULL) LOG_warn("-san_nodefault has no effect when -sans is used"); - if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT, + if (!OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT, 1)) { LOG_err("Failed to set 'SubjectAltName_nodefault' field of CMP context"); goto err; @@ -1040,7 +1172,7 @@ static int setup_ctx(CMP_CTX *ctx) return err; err = CMP_R_INVALID_ARGS; - if (!OSSL_CMP_CTX_set_log_verbosity(ctx, (int)opt_verbosity)) + if (!OSSL_CMP_CTX_set_log_verbosity(ctx->osslctx, (int)opt_verbosity)) return err; if (opt_extracerts != NULL) { STACK_OF(X509) *certs = @@ -1053,7 +1185,7 @@ static int setup_ctx(CMP_CTX *ctx) err = CMP_R_LOAD_CERTS; goto err; } else { - if (!OSSL_CMP_CTX_set1_extraCertsOut(ctx, certs)) { + if (!OSSL_CMP_CTX_set1_extraCertsOut(ctx->osslctx, certs)) { LOG_err("Failed to set 'extraCerts' field of CMP context"); CERTS_free(certs); err = -05; @@ -1078,31 +1210,51 @@ static int setup_ctx(CMP_CTX *ctx) goto err; } /* set option flags directly via CMP API */ - if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, + if (!OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, opt_unprotected_errors ? 1 : 0) #if OPENSSL_4_1_FEATURES - || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES, + || !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES, opt_nonmatched_error_nonces ? 1 : 0) #endif #if OPENSSL_3_3_FEATURES || (opt_no_cache_extracerts && /* TODO remove this condition, which is just a workaround for wrong variant of OSSL_CMP_CTX_set_option() being called */ - !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_NO_CACHE_EXTRACERTS, + !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_NO_CACHE_EXTRACERTS, opt_no_cache_extracerts ? 1 : 0)) #endif - || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_IGNORE_KEYUSAGE, + || !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_IGNORE_KEYUSAGE, opt_ignore_keyusage ? 1 : 0) - || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_VALIDITY_DAYS, + || !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_VALIDITY_DAYS, (int)opt_days) || (opt_popo >= OSSL_CRMF_POPO_NONE - && !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, + && !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_POPO_METHOD, (int)opt_popo)) - || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DISABLE_CONFIRM, + || !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_DISABLE_CONFIRM, opt_disable_confirm ? 1 : 0) - || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, + || !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_UNPROTECTED_SEND, opt_unprotected_requests ? 1 : 0)) { LOG_err("Failed to set option flags of CMP context"); goto err; } + if (opt_rats) { + if (opt_tpm_kd_req.token_name == NULL || + opt_tpm_kd_req.config_path == NULL || + opt_tpm_kd_req.plugconf_path == NULL || + opt_tpm_kd_req.nonce == NULL || + + opt_attest_chal.token_name == NULL || + opt_attest_chal.config_path == NULL || + opt_attest_chal.plugconf_path == NULL || + opt_attest_chal.nonce == NULL + ) { + LOG_err("Incomplete RATS configuration"); + goto err; + } + ctx->do_rats = true; + ctx->tpm_kd_req = opt_tpm_kd_req; + ctx->tpm_kd_req.nonce_size=strlen((char*)ctx->tpm_kd_req.nonce); + ctx->attest_chal = opt_attest_chal; + ctx->attest_chal.nonce_size=strlen((char*)ctx->attest_chal.nonce); + } if (opt_profile != NULL) { #if OPENSSL_3_3_FEATURES @@ -1114,7 +1266,7 @@ static int setup_ctx(CMP_CTX *ctx) if (err != CMP_OK) goto err; } - if (opt_geninfo != NULL && (err = handle_opt_geninfo(ctx)) != CMP_OK) + if (opt_geninfo != NULL && (err = handle_opt_geninfo(ctx->osslctx)) != CMP_OK) goto err; err = CMP_OK; @@ -1122,6 +1274,7 @@ static int setup_ctx(CMP_CTX *ctx) return err; } + static CMP_err prepare_CMP_client(CMP_CTX **pctx, enum use_case use_case, OPTIONAL LOG_cb_t log_fn) { @@ -1133,7 +1286,6 @@ static CMP_err prepare_CMP_client(CMP_CTX **pctx, enum use_case use_case, OSSL_CMP_transfer_cb_t transfer_fn = NULL; /* default HTTP(S) transfer */ const bool implicit_confirm = opt_implicit_confirm; CMP_err err = -02; - use_case = use_case + 0; /* prevent warning on unused parameter */ const char *new_cert_trusted = opt_out_trusted == NULL ? opt_srvcert : opt_out_trusted; @@ -1255,7 +1407,7 @@ static CMP_err prepare_CMP_client(CMP_CTX **pctx, enum use_case use_case, "directly trusted CMP server certificate", -1 /* no type check */, vpm); - if (srvcert == NULL || !OSSL_CMP_CTX_set1_srvCert(*pctx, srvcert)) + if (srvcert == NULL || !OSSL_CMP_CTX_set1_srvCert((*pctx)->osslctx, srvcert)) err = -8; X509_free(srvcert); } @@ -1369,7 +1521,7 @@ static int setup_transfer(CMP_CTX *ctx) SSL_CTX *tls = NULL; if (opt_tls_used - && (tls = setup_TLS(OSSL_CMP_CTX_get0_untrusted(ctx))) == NULL) { + && (tls = setup_TLS(OSSL_CMP_CTX_get0_untrusted(ctx->osslctx))) == NULL) { LOG_err("Unable to set up TLS for CMP client"); err = -16; goto err; @@ -1842,7 +1994,7 @@ static CMP_err check_set_template_options(CMP_CTX *ctx, EVP_PKEY **new_pkey, ? "fallback public key for cert to be enrolled" : "public key for checking cert resulting from p10cr"; pkey = load_pubkey_pwd(file, FORMAT_UNDEF, pass, NULL, desc); - if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, 0, pkey)) { + if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx->osslctx, 0, pkey)) { EVP_PKEY_free(pkey); return -41; } @@ -1929,7 +2081,7 @@ static CMP_err check_set_template_options(CMP_CTX *ctx, EVP_PKEY **new_pkey, use_case == revocation ? "cert to be revoked" : "reference certificate (oldcert)", -1 /* no type check */, vpm); - if (*oldcert == NULL || !OSSL_CMP_CTX_set1_oldCert(ctx, *oldcert)) + if (*oldcert == NULL || !OSSL_CMP_CTX_set1_oldCert(ctx->osslctx, *oldcert)) return -46; } } @@ -1939,7 +2091,7 @@ static CMP_err check_set_template_options(CMP_CTX *ctx, EVP_PKEY **new_pkey, } else { if ((*csr = CSR_load(opt_csr, "PKCS#10 CSR")) == NULL) return -47; - if (!OSSL_CMP_CTX_set1_p10CSR(ctx, *csr)) + if (!OSSL_CMP_CTX_set1_p10CSR(ctx->osslctx, *csr)) return -48; } } @@ -1955,7 +2107,7 @@ static CMP_err check_set_template_options(CMP_CTX *ctx, EVP_PKEY **new_pkey, LOG(FL_ERR, "Cannot read serial number: '%s'", opt_serial); return -71; } - if (!OSSL_CMP_CTX_set1_serialNumber(ctx, sno)) { + if (!OSSL_CMP_CTX_set1_serialNumber(ctx->osslctx, sno)) { ASN1_INTEGER_free(sno); LOG_err("Out of memory"); return -72; @@ -2043,7 +2195,7 @@ CMP_err save_certs(STACK_OF(X509) *certs, const char *field, const char *desc, static CMP_err save_credentials(CMP_CTX *ctx, CREDENTIALS *new_creds, enum use_case use_case) { - CMP_err err = save_certs(OSSL_CMP_CTX_get1_extraCertsIn(ctx), + CMP_err err = save_certs(OSSL_CMP_CTX_get1_extraCertsIn(ctx->osslctx), "extraCerts", "extra", opt_extracerts_dir, opt_extracertsout, opt_extracerts_dir_format); @@ -2053,7 +2205,7 @@ static CMP_err save_credentials(CMP_CTX *ctx, CREDENTIALS *new_creds, if (use_case == revocation || use_case == genm || use_case == validate) return CMP_OK; - err = save_certs(OSSL_CMP_CTX_get1_caPubs(ctx), "caPubs", "CA", + err = save_certs(OSSL_CMP_CTX_get1_caPubs(ctx->osslctx), "caPubs", "CA", opt_cacerts_dir, opt_cacertsout, opt_cacerts_dir_format); if (err != CMP_OK) return err; @@ -2240,10 +2392,10 @@ static CMP_err do_genm(CMP_CTX *ctx, X509 *oldcert) err = -58; } } else { - if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans + if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans || err == CMP_R_GET_ITAV)) err = CMP_OK; /* not checking response as we did not send request */ - else if (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans) + else if (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans) LOG(FL_ERR, "Could not obtain valid response message on genm requesting caCerts"); } CERTS_free(cacerts); @@ -2273,10 +2425,10 @@ static CMP_err do_genm(CMP_CTX *ctx, X509 *oldcert) err = CMPclient_rootCaCert(ctx, oldwithold, &newwithnew, &newwithold, &oldwithnew); if (err != CMP_OK) { - if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans + if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans || err == CMP_R_GET_ITAV)) err = CMP_OK; /* not checking response as we did not send request */ - else if (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans) + else if (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans) LOG(FL_ERR, "Could not obtain valid response message on genm requesting rootCaCert"); goto end_upd; } @@ -2336,10 +2488,10 @@ static CMP_err do_genm(CMP_CTX *ctx, X509 *oldcert) err = CMPclient_crlUpdate(ctx, crlcert != NULL ? crlcert : oldcert, oldcrl, &crl); if (err != CMP_OK) { - if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans + if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans || err == CMP_R_GET_ITAV)) err = CMP_OK; /* not checking response as we did not send request */ - else if (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans) + else if (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans) LOG(FL_ERR, "Could not obtain valid response message on genm requesting crlUpdate"); goto end_crlupd; } @@ -2371,10 +2523,10 @@ static CMP_err do_genm(CMP_CTX *ctx, X509 *oldcert) err = CMPclient_certReqTemplate(ctx, &certTemplate, &keySpec); if (err != CMP_OK) { - if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans + if (reqout_only_done && (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans || err == CMP_R_GET_ITAV)) err = CMP_OK; /* not checking response as we did not send request */ - else if (OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans) + else if (OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans) LOG(FL_ERR, "Could not obtain valid response message on genm requesting certReqTemplate"); return err; } @@ -2406,15 +2558,15 @@ static CMP_err do_genm(CMP_CTX *ctx, X509 *oldcert) LOG(FL_WARN, "No specific support for -infotype %s available in OpenSSL version %lx", opt_infotype, OpenSSL_version_num()); - if (req == NULL || !OSSL_CMP_CTX_push0_genm_ITAV(ctx, req)) { + if (req == NULL || !OSSL_CMP_CTX_push0_genm_ITAV(ctx->osslctx, req)) { LOG(FL_ERR, "Failed to create genm for -infotype %s", opt_infotype); return -24; } } - STACK_OF(OSSL_CMP_ITAV) *itavs = OSSL_CMP_exec_GENM_ses(ctx); - if (reqout_only_done && OSSL_CMP_CTX_get_status(ctx) == OSSL_CMP_PKISTATUS_trans) + STACK_OF(OSSL_CMP_ITAV) *itavs = OSSL_CMP_exec_GENM_ses(ctx->osslctx); + if (reqout_only_done && OSSL_CMP_CTX_get_status(ctx->osslctx) == OSSL_CMP_PKISTATUS_trans) return CMP_OK; /* not checking response as we did not send request */ if (itavs != NULL) { int res = print_itavs(itavs); @@ -2422,7 +2574,7 @@ static CMP_err do_genm(CMP_CTX *ctx, X509 *oldcert) sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); return res ? CMP_OK : -25; } - if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_request) + if (OSSL_CMP_CTX_get_status(ctx->osslctx) != OSSL_CMP_PKISTATUS_request) LOG(FL_ERR, "Did not receive response on genm or genp is not valid"); return -26; } @@ -2454,6 +2606,80 @@ static int CMPclient(enum use_case use_case, OPTIONAL LOG_cb_t log_fn) &exts, use_case)) != CMP_OK) goto err; + if (ctx->do_rats) { + // RATS configured + // Request TPM key data + struct token_resp req_resp; + unsigned int status = atg_generate_evidence(ctx->tpm_kd_req, &req_resp); + if (status != ATG_SUCCESS) { + LOG_err("Request TPM key data failed"); + goto err; + } + // TODO find OID for TPM key data + ASN1_OBJECT *type = OBJ_txt2obj("1.2.3.4.5", 1); + if (type == NULL) { + LOG_err("OBJ_txt2obj failed"); + goto err; + } + ASN1_OCTET_STRING* octetstring = ASN1_OCTET_STRING_new(); + if (octetstring == NULL) { + LOG_err("ASN1_OCTET_STRING_new failed"); + goto err; + } + if (!ASN1_OCTET_STRING_set( + octetstring, req_resp.submods->buf, (int)req_resp.submods->buf_size)) { + LOG_err("ASN1_OCTET_STRING_set failed"); + goto err; + } + atg_free_attestation_token(req_resp); + ASN1_TYPE* val = ASN1_TYPE_new(); + if (val == NULL) { + LOG_err("ASN1_TYPE_new failed"); + goto err; + } + ASN1_TYPE_set(val, V_ASN1_OCTET_STRING, octetstring); + + OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_create(type, val); + if (itav == NULL) { + LOG_err("OSSL_CMP_ITAV_create failed"); + goto err; + } + if (!OSSL_CMP_CTX_push0_genm_ITAV(ctx->osslctx, itav)) { + LOG_err("OSSL_CMP_CTX_push0_genm_ITAV failed"); + goto err; + } + + STACK_OF(OSSL_CMP_ITAV) *itavs = OSSL_CMP_exec_GENM_ses(ctx->osslctx); + + if (itavs == NULL || sk_OSSL_CMP_ITAV_num(itavs) != 1) { + LOG_err("Missing attestation challenge in GENP"); + goto err; + } + + OSSL_CMP_ITAV* ret_itav=sk_OSSL_CMP_ITAV_value(itavs, 0); + if (ret_itav == NULL) { + LOG_err("sk_OSSL_CMP_ITAV_value failed"); + goto err; + } + + ASN1_TYPE* ret_val=OSSL_CMP_ITAV_get0_value(ret_itav); + if (ASN1_TYPE_get(ret_val) != V_ASN1_OCTET_STRING) { + LOG_err("attestation challenge in GENP has wrong type"); + goto err; + } + + ctx->attest_chal.user_data_size = (size_t)ret_val->value.octet_string->length; + ctx->attest_chal.user_data = ret_val->value.octet_string->data; + + if (!add_rats_extensions(ctx, &exts)) + goto err; + + sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); + + } + + + if (opt_revreason < CRL_REASON_NONE || opt_revreason > CRL_REASON_AA_COMPROMISE || opt_revreason == 7) { @@ -2492,7 +2718,7 @@ static int CMPclient(enum use_case use_case, OPTIONAL LOG_cb_t log_fn) err = -19; } - int status = OSSL_CMP_CTX_get_status(ctx); + int status = OSSL_CMP_CTX_get_status(ctx->osslctx); if (status < OSSL_CMP_PKISTATUS_accepted && reqout_only_done) { /* we got no response because we did not send request */ ERR_clear_error(); @@ -2520,7 +2746,7 @@ static int CMPclient(enum use_case use_case, OPTIONAL LOG_cb_t log_fn) } #if OPENSSL_3_2_FEATURES - if (!save_cert_or_delete(OSSL_CMP_CTX_get0_validatedSrvCert(ctx), + if (!save_cert_or_delete(OSSL_CMP_CTX_get0_validatedSrvCert(ctx->osslctx), opt_srvcertout, "validated server cert")) err = -53; #endif diff --git a/src/genericCMPClient.c b/src/genericCMPClient.c index e726a4e6..5f1dcc1b 100644 --- a/src/genericCMPClient.c +++ b/src/genericCMPClient.c @@ -141,7 +141,7 @@ static int certConf_caPubs_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, cons return ret; } -CMP_err CMPclient_prepare(OSSL_CMP_CTX **pctx, +CMP_err CMPclient_prepare(CMP_CTX **pctx, OSSL_LIB_CTX *libctx, const char *propq, OPTIONAL LOG_cb_t log_fn, OPTIONAL X509_STORE *cmp_truststore, @@ -160,6 +160,12 @@ CMP_err CMPclient_prepare(OSSL_CMP_CTX **pctx, if (pctx == NULL) return CMP_R_NULL_ARGUMENT; + + *pctx = OPENSSL_malloc(sizeof(CMP_CTX)); + if (*pctx == NULL) { + goto err; + } + if ((ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL || !OSSL_CMP_CTX_set_log_cb(ctx, log_fn != NULL ? (OSSL_CMP_log_cb_t)log_fn : @@ -279,11 +285,13 @@ CMP_err CMPclient_prepare(OSSL_CMP_CTX **pctx, goto err; } - *pctx = ctx; + (*pctx)->osslctx = ctx; return CMP_OK; err: OSSL_CMP_CTX_free(ctx); + OPENSSL_free(*pctx); + *pctx = NULL; return CMPOSSL_error(); } @@ -293,13 +301,13 @@ CMP_err CMPclient_setup_BIO(CMP_CTX *ctx, BIO *rw, OPTIONAL const char *path, { if (ctx == NULL) return CMP_R_INVALID_CONTEXT; - if (!OSSL_CMP_CTX_set1_serverPath(ctx, path /* may be NULL */) || - (timeout >= 0 && !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT, + if (!OSSL_CMP_CTX_set1_serverPath(ctx->osslctx, path /* may be NULL */) || + (timeout >= 0 && !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_MSG_TIMEOUT, timeout)) || - (keep_alive >= 0 && !OSSL_CMP_CTX_set_option(ctx, + (keep_alive >= 0 && !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_KEEP_ALIVE, keep_alive)) || - !OSSL_CMP_CTX_set_transfer_cb_arg(ctx, rw)) + !OSSL_CMP_CTX_set_transfer_cb_arg(ctx->osslctx, rw)) return CMPOSSL_error(); if (rw != NULL) { @@ -430,7 +438,7 @@ static int is_localhost(const char *host) #endif /* ndef GENCMP_NO_TLS */ /* Will return error when used with OpenSSL compiled with OPENSSL_NO_SOCK. */ -CMP_err CMPclient_setup_HTTP(OSSL_CMP_CTX *ctx, const char *server, const char *path, +CMP_err CMPclient_setup_HTTP(CMP_CTX *ctx, const char *server, const char *path, int keep_alive, int timeout, OPTIONAL SSL_CTX *tls, OPTIONAL const char *proxy, OPTIONAL const char *no_proxy) @@ -462,16 +470,16 @@ CMP_err CMPclient_setup_HTTP(OSSL_CMP_CTX *ctx, const char *server, const char * LOG(FL_ERR, "Missing TLS context since server URL indicates HTTPS"); goto err; } - if (!OSSL_CMP_CTX_set1_server(ctx, host) || - (!OSSL_CMP_CTX_set_serverPort(ctx, port))) { + if (!OSSL_CMP_CTX_set1_server(ctx->osslctx, host) || + (!OSSL_CMP_CTX_set_serverPort(ctx->osslctx, port))) { err = CMPOSSL_error(); goto err; } if (path == NULL) path = parsed_path; - if (!OSSL_CMP_CTX_set1_proxy(ctx, proxy) || - !OSSL_CMP_CTX_set1_no_proxy(ctx, no_proxy)) { + if (!OSSL_CMP_CTX_set1_proxy(ctx->osslctx, proxy) || + !OSSL_CMP_CTX_set1_no_proxy(ctx->osslctx, no_proxy)) { err = CMPOSSL_error(); goto err; } @@ -503,7 +511,7 @@ CMP_err CMPclient_setup_HTTP(OSSL_CMP_CTX *ctx, const char *server, const char * } } - if (!OSSL_CMP_CTX_set_http_cb(ctx, app_http_tls_cb)) { + if (!OSSL_CMP_CTX_set_http_cb(ctx->osslctx, app_http_tls_cb)) { err = CMPOSSL_error(); goto err; } @@ -512,10 +520,10 @@ CMP_err CMPclient_setup_HTTP(OSSL_CMP_CTX *ctx, const char *server, const char * err = CMPOSSL_error(); goto err; } - APP_HTTP_TLS_INFO_free(OSSL_CMP_CTX_get_http_cb_arg(ctx)); - (void)OSSL_CMP_CTX_set_http_cb_arg(ctx, info); + APP_HTTP_TLS_INFO_free(OSSL_CMP_CTX_get_http_cb_arg(ctx->osslctx)); + (void)OSSL_CMP_CTX_set_http_cb_arg(ctx->osslctx, info); /* info will be freed along with ctx */ - OSSL_CMP_CTX_set_transfer_cb_arg(ctx, NULL); /* indicate SSL not used */ + OSSL_CMP_CTX_set_transfer_cb_arg(ctx->osslctx, NULL); /* indicate SSL not used */ if (!CONN_IS_IP_ADDR(hostaddr)) { if (hostaddr == NULL) { @@ -528,7 +536,7 @@ CMP_err CMPclient_setup_HTTP(OSSL_CMP_CTX *ctx, const char *server, const char * info->server = OPENSSL_strdup(host); info->port = OPENSSL_strdup(server_port); info->use_proxy = proxy_host != NULL; - info->timeout = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT); + info->timeout = OSSL_CMP_CTX_get_option(ctx->osslctx, OSSL_CMP_OPT_MSG_TIMEOUT); if (info->server == NULL || info->port == NULL || !SSL_CTX_up_ref(tls)) { err = CMPOSSL_error(); goto err; @@ -588,7 +596,7 @@ CMP_err CMPclient_add_certProfile(CMP_CTX *ctx, OPTIONAL const char *name) } if (name == NULL) { - if (!OSSL_CMP_CTX_reset_geninfo_ITAVs(ctx)) + if (!OSSL_CMP_CTX_reset_geninfo_ITAVs(ctx->osslctx)) goto err; } else { OSSL_CMP_ITAV *itav = NULL; @@ -601,7 +609,7 @@ CMP_err CMPclient_add_certProfile(CMP_CTX *ctx, OPTIONAL const char *name) sk_ASN1_UTF8STRING_pop_free(sk, ASN1_UTF8STRING_free); goto err; } - if (!OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) { + if (!OSSL_CMP_CTX_push0_geninfo_ITAV(ctx->osslctx, itav)) { OSSL_CMP_ITAV_free(itav); goto err; } @@ -614,7 +622,7 @@ CMP_err CMPclient_add_certProfile(CMP_CTX *ctx, OPTIONAL const char *name) } #endif /* OPENSSL_3_3_FEATURES */ -CMP_err CMPclient_setup_certreq(OSSL_CMP_CTX *ctx, +CMP_err CMPclient_setup_certreq(CMP_CTX *ctx, OPTIONAL const EVP_PKEY *new_key, OPTIONAL const X509 *old_cert, OPTIONAL const X509_NAME *subject, @@ -626,19 +634,19 @@ CMP_err CMPclient_setup_certreq(OSSL_CMP_CTX *ctx, return CMP_R_INVALID_CONTEXT; } - if (old_cert != NULL && !OSSL_CMP_CTX_set1_oldCert(ctx, (X509 *)old_cert)) + if (old_cert != NULL && !OSSL_CMP_CTX_set1_oldCert(ctx->osslctx, (X509 *)old_cert)) goto err; if (new_key != NULL) { if (!EVP_PKEY_up_ref((EVP_PKEY *)new_key)) goto err; - if (!OSSL_CMP_CTX_set0_newPkey(ctx, 1 /* priv */, + if (!OSSL_CMP_CTX_set0_newPkey(ctx->osslctx, 1 /* priv */, (EVP_PKEY *)new_key)) { EVP_PKEY_free((EVP_PKEY *)new_key); goto err; } } - if (subject != NULL && !OSSL_CMP_CTX_set1_subjectName(ctx, subject)) + if (subject != NULL && !OSSL_CMP_CTX_set1_subjectName(ctx->osslctx, subject)) goto err; if (exts != NULL) { @@ -649,11 +657,11 @@ CMP_err CMPclient_setup_certreq(OSSL_CMP_CTX *ctx, X509_EXTENSION_free); if (exts_copy == NULL - || !OSSL_CMP_CTX_set0_reqExtensions(ctx, exts_copy)) + || !OSSL_CMP_CTX_set0_reqExtensions(ctx->osslctx, exts_copy)) goto err; } - if (csr != NULL && !OSSL_CMP_CTX_set1_p10CSR(ctx, csr)) + if (csr != NULL && !OSSL_CMP_CTX_set1_p10CSR(ctx->osslctx, csr)) goto err; return CMP_OK; @@ -662,7 +670,7 @@ CMP_err CMPclient_setup_certreq(OSSL_CMP_CTX *ctx, return CMPOSSL_error(); } -CMP_err CMPclient_enroll(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) +CMP_err CMPclient_enroll(CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) { X509 *newcert = NULL; @@ -670,7 +678,7 @@ CMP_err CMPclient_enroll(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) LOG(FL_ERR, "No ctx parameter given"); return CMP_R_INVALID_CONTEXT; } - if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_unspecified) { + if (OSSL_CMP_CTX_get_status(ctx->osslctx) != OSSL_CMP_PKISTATUS_unspecified) { LOG(FL_ERR, "The ctx parameter is not clean - call CMPclient_reinit()"); return CMP_R_INVALID_CONTEXT; } @@ -681,16 +689,16 @@ CMP_err CMPclient_enroll(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) switch (cmd) { case CMP_IR: - newcert = OSSL_CMP_exec_IR_ses(ctx); + newcert = OSSL_CMP_exec_IR_ses(ctx->osslctx); break; case CMP_CR: - newcert = OSSL_CMP_exec_CR_ses(ctx); + newcert = OSSL_CMP_exec_CR_ses(ctx->osslctx); break; case CMP_P10CR: - newcert = OSSL_CMP_exec_P10CR_ses(ctx); + newcert = OSSL_CMP_exec_P10CR_ses(ctx->osslctx); break; case CMP_KUR: - newcert = OSSL_CMP_exec_KUR_ses(ctx); + newcert = OSSL_CMP_exec_KUR_ses(ctx->osslctx); break; default: LOG(FL_ERR, "Argument must be CMP_IR, CMP_CR, CMP_P10CR, or CMP_KUR"); @@ -701,15 +709,15 @@ CMP_err CMPclient_enroll(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) goto err; EVP_PKEY *new_key = - OSSL_CMP_CTX_get0_newPkey(ctx, 1 /* priv */); /* NULL in case P10CR */ - X509_STORE *new_cert_truststore = OSSL_CMP_CTX_get_certConf_cb_arg(ctx); + OSSL_CMP_CTX_get0_newPkey(ctx->osslctx, 1 /* priv */); /* NULL in case P10CR */ + X509_STORE *new_cert_truststore = OSSL_CMP_CTX_get_certConf_cb_arg(ctx->osslctx); STACK_OF(X509) *untrusted = - OSSL_CMP_CTX_get0_untrusted(ctx); /* includes extraCerts */ + OSSL_CMP_CTX_get0_untrusted(ctx->osslctx); /* includes extraCerts */ LOG_debug("Trying to build chain for newly enrolled cert"); STACK_OF(X509) *chain = X509_build_chain(newcert, untrusted, new_cert_truststore /* may NULL */, - 0, OSSL_CMP_CTX_get0_libctx(ctx), - OSSL_CMP_CTX_get0_propq(ctx)); + 0, OSSL_CMP_CTX_get0_libctx(ctx->osslctx), + OSSL_CMP_CTX_get0_propq(ctx->osslctx)); if (sk_X509_num(chain) > 0) X509_free(sk_X509_shift(chain)); /* remove leaf (EE) cert */ if (new_cert_truststore != NULL) { @@ -720,7 +728,7 @@ CMP_err CMPclient_enroll(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) LOG_debug("Succeeded building proper chain for newly enrolled cert"); } else if (chain == NULL) { LOG_warn("Could not build approximate chain for newly enrolled cert, resorting to received extraCerts"); - chain = OSSL_CMP_CTX_get1_extraCertsIn(ctx); + chain = OSSL_CMP_CTX_get1_extraCertsIn(ctx->osslctx); } else { LOG_debug("Succeeded building approximate chain for newly enrolled cert"); } @@ -737,7 +745,7 @@ CMP_err CMPclient_enroll(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, int cmd) return CMPOSSL_error(); } -CMP_err CMPclient_imprint(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_imprint(CMP_CTX *ctx, CREDENTIALS **new_creds, const EVP_PKEY *new_key, const char *subject, OPTIONAL const X509_EXTENSIONS *exts) @@ -764,7 +772,7 @@ CMP_err CMPclient_imprint(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, return err; } -CMP_err CMPclient_bootstrap(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_bootstrap(CMP_CTX *ctx, CREDENTIALS **new_creds, const EVP_PKEY *new_key, const char *subject, OPTIONAL const X509_EXTENSIONS *exts) @@ -791,7 +799,7 @@ CMP_err CMPclient_bootstrap(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, return err; } -CMP_err CMPclient_pkcs10(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_pkcs10(CMP_CTX *ctx, CREDENTIALS **new_creds, const X509_REQ *csr) { if (csr == NULL) { @@ -825,7 +833,7 @@ static STACK_OF(X509_EXTENSION) *shallow_copy_non_KID_exts(const STACK_OF(X509_E return new; } -CMP_err CMPclient_update_anycert(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_update_anycert(CMP_CTX *ctx, CREDENTIALS **new_creds, OPTIONAL const X509 *old_cert, OPTIONAL const EVP_PKEY *new_key) { @@ -840,13 +848,13 @@ CMP_err CMPclient_update_anycert(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, return ret; } -CMP_err CMPclient_update(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_update(CMP_CTX *ctx, CREDENTIALS **new_creds, OPTIONAL const EVP_PKEY *new_key) { return CMPclient_update_with_exts(ctx, new_creds, NULL, new_key, NULL); } -CMP_err CMPclient_update_with_exts(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, +CMP_err CMPclient_update_with_exts(CMP_CTX *ctx, CREDENTIALS **new_creds, OPTIONAL const X509 *old_cert, OPTIONAL const EVP_PKEY *new_key, OPTIONAL const X509_EXTENSIONS *exts) @@ -859,13 +867,13 @@ CMP_err CMPclient_update_with_exts(OSSL_CMP_CTX *ctx, CREDENTIALS **new_creds, return err; } -CMP_err CMPclient_revoke(OSSL_CMP_CTX *ctx, const X509 *cert, /* TODO: X509_REQ *csr, */ int reason) +CMP_err CMPclient_revoke(CMP_CTX *ctx, const X509 *cert, /* TODO: X509_REQ *csr, */ int reason) { if (ctx == NULL) { LOG(FL_ERR, "No ctx parameter given"); return CMP_R_INVALID_CONTEXT; } - if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_unspecified) { + if (OSSL_CMP_CTX_get_status(ctx->osslctx) != OSSL_CMP_PKISTATUS_unspecified) { LOG(FL_ERR, "The ctx parameter is not clean - call CMPclient_reinit()"); return CMP_R_INVALID_CONTEXT; } @@ -877,18 +885,18 @@ CMP_err CMPclient_revoke(OSSL_CMP_CTX *ctx, const X509 *cert, /* TODO: X509_REQ } #endif if (cert != NULL) { - if (!OSSL_CMP_CTX_set1_oldCert(ctx, (X509 *)cert)) + if (!OSSL_CMP_CTX_set1_oldCert(ctx->osslctx, (X509 *)cert)) goto err; } else { #if 0 /* TODO enable, and check why cert == NULL is accepted by Mock server */ - if (!OSSL_CMP_CTX_set1_p10CSR(ctx, csr)) + if (!OSSL_CMP_CTX_set1_p10CSR(ctx->osslctx, csr)) goto err; #endif } if ((reason >= CRL_REASON_UNSPECIFIED && - !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_REVOCATION_REASON, reason)) - || !OSSL_CMP_exec_RR_ses(ctx)) + !OSSL_CMP_CTX_set_option(ctx->osslctx, OSSL_CMP_OPT_REVOCATION_REASON, reason)) + || !OSSL_CMP_exec_RR_ses(ctx->osslctx)) goto err; ERR_clear_error(); /* empty the OpenSSL error queue */ return CMP_OK; @@ -1025,7 +1033,7 @@ CMP_err CMPclient_caCerts(CMP_CTX *ctx, STACK_OF(X509) **out) OSSL_CMP_ITAV_free(itav); return err; # else - return OSSL_CMP_get1_caCerts(ctx, out) ? CMP_OK : CMPOSSL_error(); + return OSSL_CMP_get1_caCerts(ctx->osslctx, out) ? CMP_OK : CMPOSSL_error(); # endif } #endif /* OPENSSL_3_2_FEATURES */ @@ -1061,7 +1069,7 @@ CMP_err CMPclient_certReqTemplate(CMP_CTX *ctx, OSSL_CMP_ITAV_free(itav); return err; # else - return OSSL_CMP_get1_certReqTemplate(ctx, certTemplate, keySpec) ? CMP_OK : CMPOSSL_error(); + return OSSL_CMP_get1_certReqTemplate(ctx->osslctx, certTemplate, keySpec) ? CMP_OK : CMPOSSL_error(); # endif } #endif /* OPENSSL_3_4_FEATURES */ @@ -1227,7 +1235,7 @@ CMP_err CMPclient_rootCaCert(CMP_CTX *ctx, OSSL_CMP_ITAV_free(itav); return err; # else - return OSSL_CMP_get1_rootCaKeyUpdate(ctx, oldWithOld, newWithNew, newWithOld, + return OSSL_CMP_get1_rootCaKeyUpdate(ctx->osslctx, oldWithOld, newWithNew, newWithOld, oldWithNew) ? CMP_OK : CMPOSSL_error(); # endif } @@ -1300,38 +1308,39 @@ CMP_err CMPclient_crlUpdate(CMP_CTX *ctx, OPTIONAL const X509 *cert, OSSL_CMP_ITAV_free(itav); return err; # else - return OSSL_CMP_get1_crlUpdate(ctx, cert, last_crl, crl) ? CMP_OK : CMPOSSL_error(); + return OSSL_CMP_get1_crlUpdate(ctx->osslctx, cert, last_crl, crl) ? CMP_OK : CMPOSSL_error(); # endif } #endif /* OPENSSL_3_4_FEATURES */ -char *CMPclient_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf, +char *CMPclient_snprint_PKIStatus(const CMP_CTX *ctx, char *buf, size_t bufsize) { - return OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, bufsize); + return OSSL_CMP_CTX_snprint_PKIStatus(ctx->osslctx, buf, bufsize); } -CMP_err CMPclient_reinit(OSSL_CMP_CTX *ctx) +CMP_err CMPclient_reinit(CMP_CTX *ctx) { - OSSL_CMP_CTX_print_errors(ctx /* may be NULL */); - if (ctx == NULL) { + OSSL_CMP_CTX_print_errors(ctx==NULL ? NULL : ctx->osslctx /* may be NULL */); + if (ctx == NULL || ctx->osslctx == NULL) { LOG(FL_ERR, "No ctx parameter given"); return CMP_R_INVALID_CONTEXT; } - return OSSL_CMP_CTX_reinit(ctx) ? CMP_OK : CMPOSSL_error(); + return OSSL_CMP_CTX_reinit(ctx->osslctx) ? CMP_OK : CMPOSSL_error(); } -void CMPclient_finish(OPTIONAL OSSL_CMP_CTX *ctx) +void CMPclient_finish(OPTIONAL CMP_CTX *ctx) { - OSSL_CMP_CTX_print_errors(ctx /* may be NULL */); - if (ctx != NULL) { + OSSL_CMP_CTX_print_errors(ctx==NULL ? NULL : ctx->osslctx /* may be NULL */); + if (ctx != NULL && ctx->osslctx != NULL) { #ifndef GENCMP_NO_TLS - BIO *rw = OSSL_CMP_CTX_get_transfer_cb_arg(ctx); - APP_HTTP_TLS_INFO *info = OSSL_CMP_CTX_get_http_cb_arg(ctx); + BIO *rw = OSSL_CMP_CTX_get_transfer_cb_arg(ctx->osslctx); + APP_HTTP_TLS_INFO *info = OSSL_CMP_CTX_get_http_cb_arg(ctx->osslctx); #endif - X509_STORE_free(OSSL_CMP_CTX_get_certConf_cb_arg(ctx)); - OSSL_CMP_CTX_free(ctx); + X509_STORE_free(OSSL_CMP_CTX_get_certConf_cb_arg(ctx->osslctx)); + OSSL_CMP_CTX_free(ctx->osslctx); + OPENSSL_free(ctx); #ifndef GENCMP_NO_TLS if (rw == NULL) APP_HTTP_TLS_INFO_free(info); diff --git a/test/recipes/80-test_cmp_http_data/Mock/server.cnf b/test/recipes/80-test_cmp_http_data/Mock/server.cnf index d3509a03..97825827 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/server.cnf +++ b/test/recipes/80-test_cmp_http_data/Mock/server.cnf @@ -1,6 +1,6 @@ [cmp] # mock server configuration -port = 0 +port = 8888 srv_secret = pass:test srv_cert = server.crt srv_key = server.key diff --git a/test/recipes/80-test_cmp_http_data/test.cnf b/test/recipes/80-test_cmp_http_data/test.cnf index 55680822..8334da63 100644 --- a/test/recipes/80-test_cmp_http_data/test.cnf +++ b/test/recipes/80-test_cmp_http_data/test.cnf @@ -52,7 +52,7 @@ EJBCA_CMP_SUBJECT_IMPRINT = # no_check_time = 1 # is not supported by OpenSSL 1.0.2 #attime = 1524704000 server_host = 127.0.0.1 # localhost -server_port = 0 # 0 means that the port is determined by the server +server_port = 8888 # 0 means that the port is determined by the server server_tls = 0 server_cert = server.crt server = $server_host:$server_port @@ -75,6 +75,9 @@ keypass = pass:12345 ignore_keyusage = 0 column = 0 sleep = 0 +reqout = "/tmp/req1.der /tmp/req2.der /tmp/req3.der /tmp/req4.der /tmp/req5.der /tmp/req6.der" +rspout = "/tmp/rsp1.der /tmp/rsp2.der /tmp/rsp3.der /tmp/rsp4.der /tmp/rsp5.der /tmp/rsp6.der" + [LwCmp] #attime = 1524704000