1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * Copyright Siemens AG 2018-2020 4e1051a39Sopenharmony_ci * 5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 6e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or atf 8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 9e1051a39Sopenharmony_ci */ 10e1051a39Sopenharmony_ci 11e1051a39Sopenharmony_ci#include "apps.h" 12e1051a39Sopenharmony_ci#include "cmp_mock_srv.h" 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#include <openssl/cmp.h> 15e1051a39Sopenharmony_ci#include <openssl/err.h> 16e1051a39Sopenharmony_ci#include <openssl/cmperr.h> 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci/* the context for the CMP mock server */ 19e1051a39Sopenharmony_citypedef struct 20e1051a39Sopenharmony_ci{ 21e1051a39Sopenharmony_ci X509 *certOut; /* certificate to be returned in cp/ip/kup msg */ 22e1051a39Sopenharmony_ci STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */ 23e1051a39Sopenharmony_ci STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */ 24e1051a39Sopenharmony_ci OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */ 25e1051a39Sopenharmony_ci int sendError; /* send error response on given request type */ 26e1051a39Sopenharmony_ci OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */ 27e1051a39Sopenharmony_ci int pollCount; /* number of polls before actual cert response */ 28e1051a39Sopenharmony_ci int curr_pollCount; /* number of polls so far for current request */ 29e1051a39Sopenharmony_ci int checkAfterTime; /* time the client should wait between polling */ 30e1051a39Sopenharmony_ci} mock_srv_ctx; 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_cistatic void mock_srv_ctx_free(mock_srv_ctx *ctx) 34e1051a39Sopenharmony_ci{ 35e1051a39Sopenharmony_ci if (ctx == NULL) 36e1051a39Sopenharmony_ci return; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci OSSL_CMP_PKISI_free(ctx->statusOut); 39e1051a39Sopenharmony_ci X509_free(ctx->certOut); 40e1051a39Sopenharmony_ci sk_X509_pop_free(ctx->chainOut, X509_free); 41e1051a39Sopenharmony_ci sk_X509_pop_free(ctx->caPubsOut, X509_free); 42e1051a39Sopenharmony_ci OSSL_CMP_MSG_free(ctx->certReq); 43e1051a39Sopenharmony_ci OPENSSL_free(ctx); 44e1051a39Sopenharmony_ci} 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_cistatic mock_srv_ctx *mock_srv_ctx_new(void) 47e1051a39Sopenharmony_ci{ 48e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OPENSSL_zalloc(sizeof(mock_srv_ctx)); 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci if (ctx == NULL) 51e1051a39Sopenharmony_ci goto err; 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL) 54e1051a39Sopenharmony_ci goto err; 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_ci ctx->sendError = -1; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci /* all other elements are initialized to 0 or NULL, respectively */ 59e1051a39Sopenharmony_ci return ctx; 60e1051a39Sopenharmony_ci err: 61e1051a39Sopenharmony_ci mock_srv_ctx_free(ctx); 62e1051a39Sopenharmony_ci return NULL; 63e1051a39Sopenharmony_ci} 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert) 66e1051a39Sopenharmony_ci{ 67e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci if (ctx == NULL) { 70e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 71e1051a39Sopenharmony_ci return 0; 72e1051a39Sopenharmony_ci } 73e1051a39Sopenharmony_ci if (cert == NULL || X509_up_ref(cert)) { 74e1051a39Sopenharmony_ci X509_free(ctx->certOut); 75e1051a39Sopenharmony_ci ctx->certOut = cert; 76e1051a39Sopenharmony_ci return 1; 77e1051a39Sopenharmony_ci } 78e1051a39Sopenharmony_ci return 0; 79e1051a39Sopenharmony_ci} 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, 82e1051a39Sopenharmony_ci STACK_OF(X509) *chain) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 85e1051a39Sopenharmony_ci STACK_OF(X509) *chain_copy = NULL; 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ci if (ctx == NULL) { 88e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 89e1051a39Sopenharmony_ci return 0; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL) 92e1051a39Sopenharmony_ci return 0; 93e1051a39Sopenharmony_ci sk_X509_pop_free(ctx->chainOut, X509_free); 94e1051a39Sopenharmony_ci ctx->chainOut = chain_copy; 95e1051a39Sopenharmony_ci return 1; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, 99e1051a39Sopenharmony_ci STACK_OF(X509) *caPubs) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 102e1051a39Sopenharmony_ci STACK_OF(X509) *caPubs_copy = NULL; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci if (ctx == NULL) { 105e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 106e1051a39Sopenharmony_ci return 0; 107e1051a39Sopenharmony_ci } 108e1051a39Sopenharmony_ci if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL) 109e1051a39Sopenharmony_ci return 0; 110e1051a39Sopenharmony_ci sk_X509_pop_free(ctx->caPubsOut, X509_free); 111e1051a39Sopenharmony_ci ctx->caPubsOut = caPubs_copy; 112e1051a39Sopenharmony_ci return 1; 113e1051a39Sopenharmony_ci} 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, 116e1051a39Sopenharmony_ci int fail_info, const char *text) 117e1051a39Sopenharmony_ci{ 118e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 119e1051a39Sopenharmony_ci OSSL_CMP_PKISI *si; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci if (ctx == NULL) { 122e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 123e1051a39Sopenharmony_ci return 0; 124e1051a39Sopenharmony_ci } 125e1051a39Sopenharmony_ci if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, text)) == NULL) 126e1051a39Sopenharmony_ci return 0; 127e1051a39Sopenharmony_ci OSSL_CMP_PKISI_free(ctx->statusOut); 128e1051a39Sopenharmony_ci ctx->statusOut = si; 129e1051a39Sopenharmony_ci return 1; 130e1051a39Sopenharmony_ci} 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype) 133e1051a39Sopenharmony_ci{ 134e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_ci if (ctx == NULL) { 137e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 138e1051a39Sopenharmony_ci return 0; 139e1051a39Sopenharmony_ci } 140e1051a39Sopenharmony_ci /* might check bodytype, but this would require exporting all body types */ 141e1051a39Sopenharmony_ci ctx->sendError = bodytype; 142e1051a39Sopenharmony_ci return 1; 143e1051a39Sopenharmony_ci} 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count) 146e1051a39Sopenharmony_ci{ 147e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci if (ctx == NULL) { 150e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 151e1051a39Sopenharmony_ci return 0; 152e1051a39Sopenharmony_ci } 153e1051a39Sopenharmony_ci if (count < 0) { 154e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); 155e1051a39Sopenharmony_ci return 0; 156e1051a39Sopenharmony_ci } 157e1051a39Sopenharmony_ci ctx->pollCount = count; 158e1051a39Sopenharmony_ci return 1; 159e1051a39Sopenharmony_ci} 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ciint ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci if (ctx == NULL) { 166e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 167e1051a39Sopenharmony_ci return 0; 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci ctx->checkAfterTime = sec; 170e1051a39Sopenharmony_ci return 1; 171e1051a39Sopenharmony_ci} 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_cistatic OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, 174e1051a39Sopenharmony_ci const OSSL_CMP_MSG *cert_req, 175e1051a39Sopenharmony_ci ossl_unused int certReqId, 176e1051a39Sopenharmony_ci const OSSL_CRMF_MSG *crm, 177e1051a39Sopenharmony_ci const X509_REQ *p10cr, 178e1051a39Sopenharmony_ci X509 **certOut, 179e1051a39Sopenharmony_ci STACK_OF(X509) **chainOut, 180e1051a39Sopenharmony_ci STACK_OF(X509) **caPubs) 181e1051a39Sopenharmony_ci{ 182e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 183e1051a39Sopenharmony_ci OSSL_CMP_PKISI *si = NULL; 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci if (ctx == NULL || cert_req == NULL 186e1051a39Sopenharmony_ci || certOut == NULL || chainOut == NULL || caPubs == NULL) { 187e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 188e1051a39Sopenharmony_ci return NULL; 189e1051a39Sopenharmony_ci } 190e1051a39Sopenharmony_ci if (ctx->sendError == 1 191e1051a39Sopenharmony_ci || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) { 192e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); 193e1051a39Sopenharmony_ci return NULL; 194e1051a39Sopenharmony_ci } 195e1051a39Sopenharmony_ci 196e1051a39Sopenharmony_ci *certOut = NULL; 197e1051a39Sopenharmony_ci *chainOut = NULL; 198e1051a39Sopenharmony_ci *caPubs = NULL; 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_ci if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) { 201e1051a39Sopenharmony_ci /* start polling */ 202e1051a39Sopenharmony_ci if (ctx->certReq != NULL) { 203e1051a39Sopenharmony_ci /* already in polling mode */ 204e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); 205e1051a39Sopenharmony_ci return NULL; 206e1051a39Sopenharmony_ci } 207e1051a39Sopenharmony_ci if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL) 208e1051a39Sopenharmony_ci return NULL; 209e1051a39Sopenharmony_ci return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL); 210e1051a39Sopenharmony_ci } 211e1051a39Sopenharmony_ci if (ctx->curr_pollCount >= ctx->pollCount) 212e1051a39Sopenharmony_ci /* give final response after polling */ 213e1051a39Sopenharmony_ci ctx->curr_pollCount = 0; 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR 216e1051a39Sopenharmony_ci && crm != NULL && ctx->certOut != NULL) { 217e1051a39Sopenharmony_ci const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm); 218e1051a39Sopenharmony_ci const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut); 219e1051a39Sopenharmony_ci const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut); 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci if (cid == NULL) { 222e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID); 223e1051a39Sopenharmony_ci return NULL; 224e1051a39Sopenharmony_ci } 225e1051a39Sopenharmony_ci if (issuer != NULL 226e1051a39Sopenharmony_ci && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) { 227e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); 228e1051a39Sopenharmony_ci return NULL; 229e1051a39Sopenharmony_ci } 230e1051a39Sopenharmony_ci if (serial != NULL 231e1051a39Sopenharmony_ci && ASN1_INTEGER_cmp(serial, 232e1051a39Sopenharmony_ci OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) { 233e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); 234e1051a39Sopenharmony_ci return NULL; 235e1051a39Sopenharmony_ci } 236e1051a39Sopenharmony_ci } 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci if (ctx->certOut != NULL 239e1051a39Sopenharmony_ci && (*certOut = X509_dup(ctx->certOut)) == NULL) 240e1051a39Sopenharmony_ci goto err; 241e1051a39Sopenharmony_ci if (ctx->chainOut != NULL 242e1051a39Sopenharmony_ci && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL) 243e1051a39Sopenharmony_ci goto err; 244e1051a39Sopenharmony_ci if (ctx->caPubsOut != NULL 245e1051a39Sopenharmony_ci && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL) 246e1051a39Sopenharmony_ci goto err; 247e1051a39Sopenharmony_ci if (ctx->statusOut != NULL 248e1051a39Sopenharmony_ci && (si = OSSL_CMP_PKISI_dup(ctx->statusOut)) == NULL) 249e1051a39Sopenharmony_ci goto err; 250e1051a39Sopenharmony_ci return si; 251e1051a39Sopenharmony_ci 252e1051a39Sopenharmony_ci err: 253e1051a39Sopenharmony_ci X509_free(*certOut); 254e1051a39Sopenharmony_ci *certOut = NULL; 255e1051a39Sopenharmony_ci sk_X509_pop_free(*chainOut, X509_free); 256e1051a39Sopenharmony_ci *chainOut = NULL; 257e1051a39Sopenharmony_ci sk_X509_pop_free(*caPubs, X509_free); 258e1051a39Sopenharmony_ci *caPubs = NULL; 259e1051a39Sopenharmony_ci return NULL; 260e1051a39Sopenharmony_ci} 261e1051a39Sopenharmony_ci 262e1051a39Sopenharmony_cistatic OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, 263e1051a39Sopenharmony_ci const OSSL_CMP_MSG *rr, 264e1051a39Sopenharmony_ci const X509_NAME *issuer, 265e1051a39Sopenharmony_ci const ASN1_INTEGER *serial) 266e1051a39Sopenharmony_ci{ 267e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 268e1051a39Sopenharmony_ci 269e1051a39Sopenharmony_ci if (ctx == NULL || rr == NULL) { 270e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 271e1051a39Sopenharmony_ci return NULL; 272e1051a39Sopenharmony_ci } 273e1051a39Sopenharmony_ci if (ctx->certOut == NULL || ctx->sendError == 1 274e1051a39Sopenharmony_ci || ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) { 275e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); 276e1051a39Sopenharmony_ci return NULL; 277e1051a39Sopenharmony_ci } 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci /* Allow any RR derived from CSR, which may include subject and serial */ 280e1051a39Sopenharmony_ci if (issuer == NULL || serial == NULL) 281e1051a39Sopenharmony_ci return OSSL_CMP_PKISI_dup(ctx->statusOut); 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_ci /* accept revocation only for the certificate we sent in ir/cr/kur */ 284e1051a39Sopenharmony_ci if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0 285e1051a39Sopenharmony_ci || ASN1_INTEGER_cmp(serial, 286e1051a39Sopenharmony_ci X509_get0_serialNumber(ctx->certOut)) != 0) { 287e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED, 288e1051a39Sopenharmony_ci "wrong certificate to revoke"); 289e1051a39Sopenharmony_ci return NULL; 290e1051a39Sopenharmony_ci } 291e1051a39Sopenharmony_ci return OSSL_CMP_PKISI_dup(ctx->statusOut); 292e1051a39Sopenharmony_ci} 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_cistatic int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, 295e1051a39Sopenharmony_ci const OSSL_CMP_MSG *genm, 296e1051a39Sopenharmony_ci const STACK_OF(OSSL_CMP_ITAV) *in, 297e1051a39Sopenharmony_ci STACK_OF(OSSL_CMP_ITAV) **out) 298e1051a39Sopenharmony_ci{ 299e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 300e1051a39Sopenharmony_ci 301e1051a39Sopenharmony_ci if (ctx == NULL || genm == NULL || in == NULL || out == NULL) { 302e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 303e1051a39Sopenharmony_ci return 0; 304e1051a39Sopenharmony_ci } 305e1051a39Sopenharmony_ci if (ctx->sendError == 1 306e1051a39Sopenharmony_ci || ctx->sendError == OSSL_CMP_MSG_get_bodytype(genm) 307e1051a39Sopenharmony_ci || sk_OSSL_CMP_ITAV_num(in) > 1) { 308e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); 309e1051a39Sopenharmony_ci return 0; 310e1051a39Sopenharmony_ci } 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup, 313e1051a39Sopenharmony_ci OSSL_CMP_ITAV_free); 314e1051a39Sopenharmony_ci return *out != NULL; 315e1051a39Sopenharmony_ci} 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_cistatic void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error, 318e1051a39Sopenharmony_ci const OSSL_CMP_PKISI *statusInfo, 319e1051a39Sopenharmony_ci const ASN1_INTEGER *errorCode, 320e1051a39Sopenharmony_ci const OSSL_CMP_PKIFREETEXT *errorDetails) 321e1051a39Sopenharmony_ci{ 322e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 323e1051a39Sopenharmony_ci char buf[OSSL_CMP_PKISI_BUFLEN]; 324e1051a39Sopenharmony_ci char *sibuf; 325e1051a39Sopenharmony_ci int i; 326e1051a39Sopenharmony_ci 327e1051a39Sopenharmony_ci if (ctx == NULL || error == NULL) { 328e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 329e1051a39Sopenharmony_ci return; 330e1051a39Sopenharmony_ci } 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ci BIO_printf(bio_err, "mock server received error:\n"); 333e1051a39Sopenharmony_ci 334e1051a39Sopenharmony_ci if (statusInfo == NULL) { 335e1051a39Sopenharmony_ci BIO_printf(bio_err, "pkiStatusInfo absent\n"); 336e1051a39Sopenharmony_ci } else { 337e1051a39Sopenharmony_ci sibuf = OSSL_CMP_snprint_PKIStatusInfo(statusInfo, buf, sizeof(buf)); 338e1051a39Sopenharmony_ci BIO_printf(bio_err, "pkiStatusInfo: %s\n", 339e1051a39Sopenharmony_ci sibuf != NULL ? sibuf: "<invalid>"); 340e1051a39Sopenharmony_ci } 341e1051a39Sopenharmony_ci 342e1051a39Sopenharmony_ci if (errorCode == NULL) 343e1051a39Sopenharmony_ci BIO_printf(bio_err, "errorCode absent\n"); 344e1051a39Sopenharmony_ci else 345e1051a39Sopenharmony_ci BIO_printf(bio_err, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode)); 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ci if (sk_ASN1_UTF8STRING_num(errorDetails) <= 0) { 348e1051a39Sopenharmony_ci BIO_printf(bio_err, "errorDetails absent\n"); 349e1051a39Sopenharmony_ci } else { 350e1051a39Sopenharmony_ci BIO_printf(bio_err, "errorDetails: "); 351e1051a39Sopenharmony_ci for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) { 352e1051a39Sopenharmony_ci if (i > 0) 353e1051a39Sopenharmony_ci BIO_printf(bio_err, ", "); 354e1051a39Sopenharmony_ci BIO_printf(bio_err, "\""); 355e1051a39Sopenharmony_ci ASN1_STRING_print(bio_err, 356e1051a39Sopenharmony_ci sk_ASN1_UTF8STRING_value(errorDetails, i)); 357e1051a39Sopenharmony_ci BIO_printf(bio_err, "\""); 358e1051a39Sopenharmony_ci } 359e1051a39Sopenharmony_ci BIO_printf(bio_err, "\n"); 360e1051a39Sopenharmony_ci } 361e1051a39Sopenharmony_ci} 362e1051a39Sopenharmony_ci 363e1051a39Sopenharmony_cistatic int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, 364e1051a39Sopenharmony_ci const OSSL_CMP_MSG *certConf, 365e1051a39Sopenharmony_ci ossl_unused int certReqId, 366e1051a39Sopenharmony_ci const ASN1_OCTET_STRING *certHash, 367e1051a39Sopenharmony_ci const OSSL_CMP_PKISI *si) 368e1051a39Sopenharmony_ci{ 369e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 370e1051a39Sopenharmony_ci ASN1_OCTET_STRING *digest; 371e1051a39Sopenharmony_ci 372e1051a39Sopenharmony_ci if (ctx == NULL || certConf == NULL || certHash == NULL) { 373e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 374e1051a39Sopenharmony_ci return 0; 375e1051a39Sopenharmony_ci } 376e1051a39Sopenharmony_ci if (ctx->sendError == 1 377e1051a39Sopenharmony_ci || ctx->sendError == OSSL_CMP_MSG_get_bodytype(certConf) 378e1051a39Sopenharmony_ci || ctx->certOut == NULL) { 379e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); 380e1051a39Sopenharmony_ci return 0; 381e1051a39Sopenharmony_ci } 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ci if ((digest = X509_digest_sig(ctx->certOut, NULL, NULL)) == NULL) 384e1051a39Sopenharmony_ci return 0; 385e1051a39Sopenharmony_ci if (ASN1_OCTET_STRING_cmp(certHash, digest) != 0) { 386e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(digest); 387e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_CERTHASH_UNMATCHED); 388e1051a39Sopenharmony_ci return 0; 389e1051a39Sopenharmony_ci } 390e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(digest); 391e1051a39Sopenharmony_ci return 1; 392e1051a39Sopenharmony_ci} 393e1051a39Sopenharmony_ci 394e1051a39Sopenharmony_cistatic int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, 395e1051a39Sopenharmony_ci const OSSL_CMP_MSG *pollReq, 396e1051a39Sopenharmony_ci ossl_unused int certReqId, 397e1051a39Sopenharmony_ci OSSL_CMP_MSG **certReq, int64_t *check_after) 398e1051a39Sopenharmony_ci{ 399e1051a39Sopenharmony_ci mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); 400e1051a39Sopenharmony_ci 401e1051a39Sopenharmony_ci if (ctx == NULL || pollReq == NULL 402e1051a39Sopenharmony_ci || certReq == NULL || check_after == NULL) { 403e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 404e1051a39Sopenharmony_ci return 0; 405e1051a39Sopenharmony_ci } 406e1051a39Sopenharmony_ci if (ctx->sendError == 1 407e1051a39Sopenharmony_ci || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) { 408e1051a39Sopenharmony_ci *certReq = NULL; 409e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); 410e1051a39Sopenharmony_ci return 0; 411e1051a39Sopenharmony_ci } 412e1051a39Sopenharmony_ci if (ctx->certReq == NULL) { 413e1051a39Sopenharmony_ci /* not currently in polling mode */ 414e1051a39Sopenharmony_ci *certReq = NULL; 415e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); 416e1051a39Sopenharmony_ci return 0; 417e1051a39Sopenharmony_ci } 418e1051a39Sopenharmony_ci 419e1051a39Sopenharmony_ci if (++ctx->curr_pollCount >= ctx->pollCount) { 420e1051a39Sopenharmony_ci /* end polling */ 421e1051a39Sopenharmony_ci *certReq = ctx->certReq; 422e1051a39Sopenharmony_ci ctx->certReq = NULL; 423e1051a39Sopenharmony_ci *check_after = 0; 424e1051a39Sopenharmony_ci } else { 425e1051a39Sopenharmony_ci *certReq = NULL; 426e1051a39Sopenharmony_ci *check_after = ctx->checkAfterTime; 427e1051a39Sopenharmony_ci } 428e1051a39Sopenharmony_ci return 1; 429e1051a39Sopenharmony_ci} 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ciOSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq) 432e1051a39Sopenharmony_ci{ 433e1051a39Sopenharmony_ci OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, propq); 434e1051a39Sopenharmony_ci mock_srv_ctx *ctx = mock_srv_ctx_new(); 435e1051a39Sopenharmony_ci 436e1051a39Sopenharmony_ci if (srv_ctx != NULL && ctx != NULL 437e1051a39Sopenharmony_ci && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request, 438e1051a39Sopenharmony_ci process_rr, process_genm, process_error, 439e1051a39Sopenharmony_ci process_certConf, process_pollReq)) 440e1051a39Sopenharmony_ci return srv_ctx; 441e1051a39Sopenharmony_ci 442e1051a39Sopenharmony_ci mock_srv_ctx_free(ctx); 443e1051a39Sopenharmony_ci OSSL_CMP_SRV_CTX_free(srv_ctx); 444e1051a39Sopenharmony_ci return NULL; 445e1051a39Sopenharmony_ci} 446e1051a39Sopenharmony_ci 447e1051a39Sopenharmony_civoid ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx) 448e1051a39Sopenharmony_ci{ 449e1051a39Sopenharmony_ci if (srv_ctx != NULL) 450e1051a39Sopenharmony_ci mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx)); 451e1051a39Sopenharmony_ci OSSL_CMP_SRV_CTX_free(srv_ctx); 452e1051a39Sopenharmony_ci} 453