xref: /third_party/openssl/crypto/cmp/cmp_ctx.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci * Copyright Nokia 2007-2019
4e1051a39Sopenharmony_ci * Copyright Siemens AG 2015-2019
5e1051a39Sopenharmony_ci *
6e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
7e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
8e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
9e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
10e1051a39Sopenharmony_ci */
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci#include <openssl/trace.h>
13e1051a39Sopenharmony_ci#include <openssl/bio.h>
14e1051a39Sopenharmony_ci#include <openssl/ocsp.h> /* for OCSP_REVOKED_STATUS_* */
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci#include "cmp_local.h"
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci/* explicit #includes not strictly needed since implied by the above: */
19e1051a39Sopenharmony_ci#include <openssl/cmp.h>
20e1051a39Sopenharmony_ci#include <openssl/crmf.h>
21e1051a39Sopenharmony_ci#include <openssl/err.h>
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ci/*
24e1051a39Sopenharmony_ci * Get current certificate store containing trusted root CA certs
25e1051a39Sopenharmony_ci */
26e1051a39Sopenharmony_ciX509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
27e1051a39Sopenharmony_ci{
28e1051a39Sopenharmony_ci    if (ctx == NULL) {
29e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
30e1051a39Sopenharmony_ci        return NULL;
31e1051a39Sopenharmony_ci    }
32e1051a39Sopenharmony_ci    return ctx->trusted;
33e1051a39Sopenharmony_ci}
34e1051a39Sopenharmony_ci
35e1051a39Sopenharmony_ci/*
36e1051a39Sopenharmony_ci * Set certificate store containing trusted (root) CA certs and possibly CRLs
37e1051a39Sopenharmony_ci * and a cert verification callback function used for CMP server authentication.
38e1051a39Sopenharmony_ci * Any already existing store entry is freed. Given NULL, the entry is reset.
39e1051a39Sopenharmony_ci */
40e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
41e1051a39Sopenharmony_ci{
42e1051a39Sopenharmony_ci    if (ctx == NULL) {
43e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
44e1051a39Sopenharmony_ci        return 0;
45e1051a39Sopenharmony_ci    }
46e1051a39Sopenharmony_ci    X509_STORE_free(ctx->trusted);
47e1051a39Sopenharmony_ci    ctx->trusted = store;
48e1051a39Sopenharmony_ci    return 1;
49e1051a39Sopenharmony_ci}
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci/* Get current list of non-trusted intermediate certs */
52e1051a39Sopenharmony_ciSTACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx)
53e1051a39Sopenharmony_ci{
54e1051a39Sopenharmony_ci    if (ctx == NULL) {
55e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
56e1051a39Sopenharmony_ci        return NULL;
57e1051a39Sopenharmony_ci    }
58e1051a39Sopenharmony_ci    return ctx->untrusted;
59e1051a39Sopenharmony_ci}
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci/*
62e1051a39Sopenharmony_ci * Set untrusted certificates for path construction in authentication of
63e1051a39Sopenharmony_ci * the CMP server and potentially others (TLS server, newly enrolled cert).
64e1051a39Sopenharmony_ci */
65e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
66e1051a39Sopenharmony_ci{
67e1051a39Sopenharmony_ci    STACK_OF(X509) *untrusted = NULL;
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 (!ossl_x509_add_certs_new(&untrusted, certs,
74e1051a39Sopenharmony_ci                                 X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
75e1051a39Sopenharmony_ci        goto err;
76e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->untrusted, X509_free);
77e1051a39Sopenharmony_ci    ctx->untrusted = untrusted;
78e1051a39Sopenharmony_ci    return 1;
79e1051a39Sopenharmony_ci err:
80e1051a39Sopenharmony_ci    sk_X509_pop_free(untrusted, X509_free);
81e1051a39Sopenharmony_ci    return 0;
82e1051a39Sopenharmony_ci}
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_cistatic int cmp_ctx_set_md(OSSL_CMP_CTX *ctx, EVP_MD **pmd, int nid)
85e1051a39Sopenharmony_ci{
86e1051a39Sopenharmony_ci    EVP_MD *md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propq);
87e1051a39Sopenharmony_ci    /* fetching in advance to be able to throw error early if unsupported */
88e1051a39Sopenharmony_ci
89e1051a39Sopenharmony_ci    if (md == NULL) {
90e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_ALGORITHM);
91e1051a39Sopenharmony_ci        return 0;
92e1051a39Sopenharmony_ci    }
93e1051a39Sopenharmony_ci    EVP_MD_free(*pmd);
94e1051a39Sopenharmony_ci    *pmd = md;
95e1051a39Sopenharmony_ci    return 1;
96e1051a39Sopenharmony_ci}
97e1051a39Sopenharmony_ci
98e1051a39Sopenharmony_ci/*
99e1051a39Sopenharmony_ci * Allocates and initializes OSSL_CMP_CTX context structure with default values.
100e1051a39Sopenharmony_ci * Returns new context on success, NULL on error
101e1051a39Sopenharmony_ci */
102e1051a39Sopenharmony_ciOSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq)
103e1051a39Sopenharmony_ci{
104e1051a39Sopenharmony_ci    OSSL_CMP_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
105e1051a39Sopenharmony_ci
106e1051a39Sopenharmony_ci    if (ctx == NULL)
107e1051a39Sopenharmony_ci        goto err;
108e1051a39Sopenharmony_ci
109e1051a39Sopenharmony_ci    ctx->libctx = libctx;
110e1051a39Sopenharmony_ci    if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)
111e1051a39Sopenharmony_ci        goto oom;
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ci    ctx->log_verbosity = OSSL_CMP_LOG_INFO;
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_ci    ctx->status = OSSL_CMP_PKISTATUS_unspecified;
116e1051a39Sopenharmony_ci    ctx->failInfoCode = -1;
117e1051a39Sopenharmony_ci
118e1051a39Sopenharmony_ci    ctx->keep_alive = 1;
119e1051a39Sopenharmony_ci    ctx->msg_timeout = -1;
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    if ((ctx->untrusted = sk_X509_new_null()) == NULL)
122e1051a39Sopenharmony_ci        goto oom;
123e1051a39Sopenharmony_ci
124e1051a39Sopenharmony_ci    ctx->pbm_slen = 16;
125e1051a39Sopenharmony_ci    if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256))
126e1051a39Sopenharmony_ci        goto err;
127e1051a39Sopenharmony_ci    ctx->pbm_itercnt = 500;
128e1051a39Sopenharmony_ci    ctx->pbm_mac = NID_hmac_sha1;
129e1051a39Sopenharmony_ci
130e1051a39Sopenharmony_ci    if (!cmp_ctx_set_md(ctx, &ctx->digest, NID_sha256))
131e1051a39Sopenharmony_ci        goto err;
132e1051a39Sopenharmony_ci    ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE;
133e1051a39Sopenharmony_ci    ctx->revocationReason = CRL_REASON_NONE;
134e1051a39Sopenharmony_ci
135e1051a39Sopenharmony_ci    /* all other elements are initialized to 0 or NULL, respectively */
136e1051a39Sopenharmony_ci    return ctx;
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_ci oom:
139e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
140e1051a39Sopenharmony_ci err:
141e1051a39Sopenharmony_ci    OSSL_CMP_CTX_free(ctx);
142e1051a39Sopenharmony_ci    return NULL;
143e1051a39Sopenharmony_ci}
144e1051a39Sopenharmony_ci
145e1051a39Sopenharmony_ci#define OSSL_CMP_ITAVs_free(itavs) \
146e1051a39Sopenharmony_ci    sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
147e1051a39Sopenharmony_ci#define X509_EXTENSIONS_free(exts) \
148e1051a39Sopenharmony_ci    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free)
149e1051a39Sopenharmony_ci#define OSSL_CMP_PKIFREETEXT_free(text) \
150e1051a39Sopenharmony_ci    sk_ASN1_UTF8STRING_pop_free(text, ASN1_UTF8STRING_free)
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ci/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
153e1051a39Sopenharmony_ciint OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
154e1051a39Sopenharmony_ci{
155e1051a39Sopenharmony_ci    if (ctx == NULL) {
156e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
157e1051a39Sopenharmony_ci        return 0;
158e1051a39Sopenharmony_ci    }
159e1051a39Sopenharmony_ci
160e1051a39Sopenharmony_ci    if (ctx->http_ctx != NULL) {
161e1051a39Sopenharmony_ci        (void)OSSL_HTTP_close(ctx->http_ctx, 1);
162e1051a39Sopenharmony_ci        ossl_cmp_debug(ctx, "disconnected from CMP server");
163e1051a39Sopenharmony_ci        ctx->http_ctx = NULL;
164e1051a39Sopenharmony_ci    }
165e1051a39Sopenharmony_ci    ctx->status = OSSL_CMP_PKISTATUS_unspecified;
166e1051a39Sopenharmony_ci    ctx->failInfoCode = -1;
167e1051a39Sopenharmony_ci
168e1051a39Sopenharmony_ci    OSSL_CMP_ITAVs_free(ctx->genm_ITAVs);
169e1051a39Sopenharmony_ci    ctx->genm_ITAVs = NULL;
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ci    return ossl_cmp_ctx_set0_statusString(ctx, NULL)
172e1051a39Sopenharmony_ci        && ossl_cmp_ctx_set0_newCert(ctx, NULL)
173e1051a39Sopenharmony_ci        && ossl_cmp_ctx_set1_newChain(ctx, NULL)
174e1051a39Sopenharmony_ci        && ossl_cmp_ctx_set1_caPubs(ctx, NULL)
175e1051a39Sopenharmony_ci        && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL)
176e1051a39Sopenharmony_ci        && ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL)
177e1051a39Sopenharmony_ci        && OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
178e1051a39Sopenharmony_ci        && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)
179e1051a39Sopenharmony_ci        && ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
180e1051a39Sopenharmony_ci}
181e1051a39Sopenharmony_ci
182e1051a39Sopenharmony_ci/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */
183e1051a39Sopenharmony_civoid OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
184e1051a39Sopenharmony_ci{
185e1051a39Sopenharmony_ci    if (ctx == NULL)
186e1051a39Sopenharmony_ci        return;
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ci    if (ctx->http_ctx != NULL) {
189e1051a39Sopenharmony_ci        (void)OSSL_HTTP_close(ctx->http_ctx, 1);
190e1051a39Sopenharmony_ci        ossl_cmp_debug(ctx, "disconnected from CMP server");
191e1051a39Sopenharmony_ci    }
192e1051a39Sopenharmony_ci    OPENSSL_free(ctx->propq);
193e1051a39Sopenharmony_ci    OPENSSL_free(ctx->serverPath);
194e1051a39Sopenharmony_ci    OPENSSL_free(ctx->server);
195e1051a39Sopenharmony_ci    OPENSSL_free(ctx->proxy);
196e1051a39Sopenharmony_ci    OPENSSL_free(ctx->no_proxy);
197e1051a39Sopenharmony_ci
198e1051a39Sopenharmony_ci    X509_free(ctx->srvCert);
199e1051a39Sopenharmony_ci    X509_free(ctx->validatedSrvCert);
200e1051a39Sopenharmony_ci    X509_NAME_free(ctx->expected_sender);
201e1051a39Sopenharmony_ci    X509_STORE_free(ctx->trusted);
202e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->untrusted, X509_free);
203e1051a39Sopenharmony_ci
204e1051a39Sopenharmony_ci    X509_free(ctx->cert);
205e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->chain, X509_free);
206e1051a39Sopenharmony_ci    EVP_PKEY_free(ctx->pkey);
207e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ctx->referenceValue);
208e1051a39Sopenharmony_ci    if (ctx->secretValue != NULL)
209e1051a39Sopenharmony_ci        OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
210e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ctx->secretValue);
211e1051a39Sopenharmony_ci    EVP_MD_free(ctx->pbm_owf);
212e1051a39Sopenharmony_ci
213e1051a39Sopenharmony_ci    X509_NAME_free(ctx->recipient);
214e1051a39Sopenharmony_ci    EVP_MD_free(ctx->digest);
215e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ctx->transactionID);
216e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ctx->senderNonce);
217e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ctx->recipNonce);
218e1051a39Sopenharmony_ci    sk_OSSL_CMP_ITAV_pop_free(ctx->geninfo_ITAVs, OSSL_CMP_ITAV_free);
219e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->extraCertsOut, X509_free);
220e1051a39Sopenharmony_ci
221e1051a39Sopenharmony_ci    EVP_PKEY_free(ctx->newPkey);
222e1051a39Sopenharmony_ci    X509_NAME_free(ctx->issuer);
223e1051a39Sopenharmony_ci    X509_NAME_free(ctx->subjectName);
224e1051a39Sopenharmony_ci    sk_GENERAL_NAME_pop_free(ctx->subjectAltNames, GENERAL_NAME_free);
225e1051a39Sopenharmony_ci    sk_X509_EXTENSION_pop_free(ctx->reqExtensions, X509_EXTENSION_free);
226e1051a39Sopenharmony_ci    sk_POLICYINFO_pop_free(ctx->policies, POLICYINFO_free);
227e1051a39Sopenharmony_ci    X509_free(ctx->oldCert);
228e1051a39Sopenharmony_ci    X509_REQ_free(ctx->p10CSR);
229e1051a39Sopenharmony_ci
230e1051a39Sopenharmony_ci    sk_OSSL_CMP_ITAV_pop_free(ctx->genm_ITAVs, OSSL_CMP_ITAV_free);
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ci    sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free);
233e1051a39Sopenharmony_ci    X509_free(ctx->newCert);
234e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->newChain, X509_free);
235e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->caPubs, X509_free);
236e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->extraCertsIn, X509_free);
237e1051a39Sopenharmony_ci
238e1051a39Sopenharmony_ci    OPENSSL_free(ctx);
239e1051a39Sopenharmony_ci}
240e1051a39Sopenharmony_ci
241e1051a39Sopenharmony_ciint ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status)
242e1051a39Sopenharmony_ci{
243e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
244e1051a39Sopenharmony_ci        return 0;
245e1051a39Sopenharmony_ci    ctx->status = status;
246e1051a39Sopenharmony_ci    return 1;
247e1051a39Sopenharmony_ci}
248e1051a39Sopenharmony_ci
249e1051a39Sopenharmony_ci/*
250e1051a39Sopenharmony_ci * Returns the PKIStatus from the last CertRepMessage
251e1051a39Sopenharmony_ci * or Revocation Response or error message, -1 on error
252e1051a39Sopenharmony_ci */
253e1051a39Sopenharmony_ciint OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx)
254e1051a39Sopenharmony_ci{
255e1051a39Sopenharmony_ci    if (ctx == NULL) {
256e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
257e1051a39Sopenharmony_ci        return -1;
258e1051a39Sopenharmony_ci    }
259e1051a39Sopenharmony_ci    return ctx->status;
260e1051a39Sopenharmony_ci}
261e1051a39Sopenharmony_ci
262e1051a39Sopenharmony_ci/*
263e1051a39Sopenharmony_ci * Returns the statusString from the last CertRepMessage
264e1051a39Sopenharmony_ci * or Revocation Response or error message, NULL on error
265e1051a39Sopenharmony_ci */
266e1051a39Sopenharmony_ciOSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx)
267e1051a39Sopenharmony_ci{
268e1051a39Sopenharmony_ci    if (ctx == NULL) {
269e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
270e1051a39Sopenharmony_ci        return NULL;
271e1051a39Sopenharmony_ci    }
272e1051a39Sopenharmony_ci    return ctx->statusString;
273e1051a39Sopenharmony_ci}
274e1051a39Sopenharmony_ci
275e1051a39Sopenharmony_ciint ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx,
276e1051a39Sopenharmony_ci                                   OSSL_CMP_PKIFREETEXT *text)
277e1051a39Sopenharmony_ci{
278e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
279e1051a39Sopenharmony_ci        return 0;
280e1051a39Sopenharmony_ci    sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free);
281e1051a39Sopenharmony_ci    ctx->statusString = text;
282e1051a39Sopenharmony_ci    return 1;
283e1051a39Sopenharmony_ci}
284e1051a39Sopenharmony_ci
285e1051a39Sopenharmony_ciint ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert)
286e1051a39Sopenharmony_ci{
287e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
288e1051a39Sopenharmony_ci        return 0;
289e1051a39Sopenharmony_ci    X509_free(ctx->validatedSrvCert);
290e1051a39Sopenharmony_ci    ctx->validatedSrvCert = cert;
291e1051a39Sopenharmony_ci    return 1;
292e1051a39Sopenharmony_ci}
293e1051a39Sopenharmony_ci
294e1051a39Sopenharmony_ci/* Set callback function for checking if the cert is ok or should be rejected */
295e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
296e1051a39Sopenharmony_ci{
297e1051a39Sopenharmony_ci    if (ctx == NULL) {
298e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
299e1051a39Sopenharmony_ci        return 0;
300e1051a39Sopenharmony_ci    }
301e1051a39Sopenharmony_ci    ctx->certConf_cb = cb;
302e1051a39Sopenharmony_ci    return 1;
303e1051a39Sopenharmony_ci}
304e1051a39Sopenharmony_ci
305e1051a39Sopenharmony_ci/*
306e1051a39Sopenharmony_ci * Set argument, respectively a pointer to a structure containing arguments,
307e1051a39Sopenharmony_ci * optionally to be used by the certConf callback.
308e1051a39Sopenharmony_ci */
309e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
310e1051a39Sopenharmony_ci{
311e1051a39Sopenharmony_ci    if (ctx == NULL) {
312e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
313e1051a39Sopenharmony_ci        return 0;
314e1051a39Sopenharmony_ci    }
315e1051a39Sopenharmony_ci    ctx->certConf_cb_arg = arg;
316e1051a39Sopenharmony_ci    return 1;
317e1051a39Sopenharmony_ci}
318e1051a39Sopenharmony_ci
319e1051a39Sopenharmony_ci/*
320e1051a39Sopenharmony_ci * Get argument, respectively the pointer to a structure containing arguments,
321e1051a39Sopenharmony_ci * optionally to be used by certConf callback.
322e1051a39Sopenharmony_ci * Returns callback argument set previously (NULL if not set or on error)
323e1051a39Sopenharmony_ci */
324e1051a39Sopenharmony_civoid *OSSL_CMP_CTX_get_certConf_cb_arg(const OSSL_CMP_CTX *ctx)
325e1051a39Sopenharmony_ci{
326e1051a39Sopenharmony_ci    if (ctx == NULL) {
327e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
328e1051a39Sopenharmony_ci        return NULL;
329e1051a39Sopenharmony_ci    }
330e1051a39Sopenharmony_ci    return ctx->certConf_cb_arg;
331e1051a39Sopenharmony_ci}
332e1051a39Sopenharmony_ci
333e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_TRACE
334e1051a39Sopenharmony_cistatic size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt,
335e1051a39Sopenharmony_ci                                    int category, int cmd, void *vdata)
336e1051a39Sopenharmony_ci{
337e1051a39Sopenharmony_ci    OSSL_CMP_CTX *ctx = vdata;
338e1051a39Sopenharmony_ci    const char *msg;
339e1051a39Sopenharmony_ci    OSSL_CMP_severity level = -1;
340e1051a39Sopenharmony_ci    char *func = NULL;
341e1051a39Sopenharmony_ci    char *file = NULL;
342e1051a39Sopenharmony_ci    int line = 0;
343e1051a39Sopenharmony_ci
344e1051a39Sopenharmony_ci    if (buf == NULL || cnt == 0 || cmd != OSSL_TRACE_CTRL_WRITE || ctx == NULL)
345e1051a39Sopenharmony_ci        return 0;
346e1051a39Sopenharmony_ci    if (ctx->log_cb == NULL)
347e1051a39Sopenharmony_ci        return 1; /* silently drop message */
348e1051a39Sopenharmony_ci
349e1051a39Sopenharmony_ci    msg = ossl_cmp_log_parse_metadata(buf, &level, &func, &file, &line);
350e1051a39Sopenharmony_ci
351e1051a39Sopenharmony_ci    if (level > ctx->log_verbosity) /* excludes the case level is unknown */
352e1051a39Sopenharmony_ci        goto end; /* suppress output since severity is not sufficient */
353e1051a39Sopenharmony_ci
354e1051a39Sopenharmony_ci    if (!ctx->log_cb(func != NULL ? func : "(no func)",
355e1051a39Sopenharmony_ci                     file != NULL ? file : "(no file)",
356e1051a39Sopenharmony_ci                     line, level, msg))
357e1051a39Sopenharmony_ci        cnt = 0;
358e1051a39Sopenharmony_ci
359e1051a39Sopenharmony_ci end:
360e1051a39Sopenharmony_ci    OPENSSL_free(func);
361e1051a39Sopenharmony_ci    OPENSSL_free(file);
362e1051a39Sopenharmony_ci    return cnt;
363e1051a39Sopenharmony_ci}
364e1051a39Sopenharmony_ci#endif
365e1051a39Sopenharmony_ci
366e1051a39Sopenharmony_ci/* Print CMP log messages (i.e., diagnostic info) via the log cb of the ctx */
367e1051a39Sopenharmony_ciint ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
368e1051a39Sopenharmony_ci                       const char *func, const char *file, int line,
369e1051a39Sopenharmony_ci                       const char *level_str, const char *format, ...)
370e1051a39Sopenharmony_ci{
371e1051a39Sopenharmony_ci    va_list args;
372e1051a39Sopenharmony_ci    char hugebuf[1024 * 2];
373e1051a39Sopenharmony_ci    int res = 0;
374e1051a39Sopenharmony_ci
375e1051a39Sopenharmony_ci    if (ctx == NULL || ctx->log_cb == NULL)
376e1051a39Sopenharmony_ci        return 1; /* silently drop message */
377e1051a39Sopenharmony_ci
378e1051a39Sopenharmony_ci    if (level > ctx->log_verbosity) /* excludes the case level is unknown */
379e1051a39Sopenharmony_ci        return 1; /* suppress output since severity is not sufficient */
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_ci    if (format == NULL)
382e1051a39Sopenharmony_ci        return 0;
383e1051a39Sopenharmony_ci
384e1051a39Sopenharmony_ci    va_start(args, format);
385e1051a39Sopenharmony_ci
386e1051a39Sopenharmony_ci    if (func == NULL)
387e1051a39Sopenharmony_ci        func = "(unset function name)";
388e1051a39Sopenharmony_ci    if (file == NULL)
389e1051a39Sopenharmony_ci        file = "(unset file name)";
390e1051a39Sopenharmony_ci    if (level_str == NULL)
391e1051a39Sopenharmony_ci        level_str = "(unset level string)";
392e1051a39Sopenharmony_ci
393e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_TRACE
394e1051a39Sopenharmony_ci    if (OSSL_TRACE_ENABLED(CMP)) {
395e1051a39Sopenharmony_ci        OSSL_TRACE_BEGIN(CMP) {
396e1051a39Sopenharmony_ci            int printed =
397e1051a39Sopenharmony_ci                BIO_snprintf(hugebuf, sizeof(hugebuf),
398e1051a39Sopenharmony_ci                             "%s:%s:%d:" OSSL_CMP_LOG_PREFIX "%s: ",
399e1051a39Sopenharmony_ci                             func, file, line, level_str);
400e1051a39Sopenharmony_ci            if (printed > 0 && (size_t)printed < sizeof(hugebuf)) {
401e1051a39Sopenharmony_ci                if (BIO_vsnprintf(hugebuf + printed,
402e1051a39Sopenharmony_ci                                  sizeof(hugebuf) - printed, format, args) > 0)
403e1051a39Sopenharmony_ci                    res = BIO_puts(trc_out, hugebuf) > 0;
404e1051a39Sopenharmony_ci            }
405e1051a39Sopenharmony_ci        } OSSL_TRACE_END(CMP);
406e1051a39Sopenharmony_ci    }
407e1051a39Sopenharmony_ci#else /* compensate for disabled trace API */
408e1051a39Sopenharmony_ci    {
409e1051a39Sopenharmony_ci        if (BIO_vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0)
410e1051a39Sopenharmony_ci            res = ctx->log_cb(func, file, line, level, hugebuf);
411e1051a39Sopenharmony_ci    }
412e1051a39Sopenharmony_ci#endif
413e1051a39Sopenharmony_ci    va_end(args);
414e1051a39Sopenharmony_ci    return res;
415e1051a39Sopenharmony_ci}
416e1051a39Sopenharmony_ci
417e1051a39Sopenharmony_ci/* Set a callback function for error reporting and logging messages */
418e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
419e1051a39Sopenharmony_ci{
420e1051a39Sopenharmony_ci    if (ctx == NULL) {
421e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
422e1051a39Sopenharmony_ci        return 0;
423e1051a39Sopenharmony_ci    }
424e1051a39Sopenharmony_ci    ctx->log_cb = cb;
425e1051a39Sopenharmony_ci
426e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_TRACE
427e1051a39Sopenharmony_ci    /* do also in case cb == NULL, to switch off logging output: */
428e1051a39Sopenharmony_ci    if (!OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_CMP,
429e1051a39Sopenharmony_ci                                 ossl_cmp_log_trace_cb, ctx))
430e1051a39Sopenharmony_ci        return 0;
431e1051a39Sopenharmony_ci#endif
432e1051a39Sopenharmony_ci
433e1051a39Sopenharmony_ci    return 1;
434e1051a39Sopenharmony_ci}
435e1051a39Sopenharmony_ci
436e1051a39Sopenharmony_ci/* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */
437e1051a39Sopenharmony_civoid OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx)
438e1051a39Sopenharmony_ci{
439e1051a39Sopenharmony_ci    if (ctx != NULL && OSSL_CMP_LOG_ERR > ctx->log_verbosity)
440e1051a39Sopenharmony_ci        return; /* suppress output since severity is not sufficient */
441e1051a39Sopenharmony_ci    OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb);
442e1051a39Sopenharmony_ci}
443e1051a39Sopenharmony_ci
444e1051a39Sopenharmony_ci/*
445e1051a39Sopenharmony_ci * Set or clear the reference value to be used for identification
446e1051a39Sopenharmony_ci * (i.e., the user name) when using PBMAC.
447e1051a39Sopenharmony_ci */
448e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
449e1051a39Sopenharmony_ci                                     const unsigned char *ref, int len)
450e1051a39Sopenharmony_ci{
451e1051a39Sopenharmony_ci    if (ctx == NULL) {
452e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
453e1051a39Sopenharmony_ci        return 0;
454e1051a39Sopenharmony_ci    }
455e1051a39Sopenharmony_ci    return ossl_cmp_asn1_octet_string_set1_bytes(&ctx->referenceValue, ref,
456e1051a39Sopenharmony_ci                                                 len);
457e1051a39Sopenharmony_ci}
458e1051a39Sopenharmony_ci
459e1051a39Sopenharmony_ci/* Set or clear the password to be used for protecting messages with PBMAC */
460e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx,
461e1051a39Sopenharmony_ci                                  const unsigned char *sec, int len)
462e1051a39Sopenharmony_ci{
463e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *secretValue = NULL;
464e1051a39Sopenharmony_ci    if (ctx == NULL) {
465e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
466e1051a39Sopenharmony_ci        return 0;
467e1051a39Sopenharmony_ci    }
468e1051a39Sopenharmony_ci    if (ossl_cmp_asn1_octet_string_set1_bytes(&secretValue, sec, len) != 1)
469e1051a39Sopenharmony_ci        return 0;
470e1051a39Sopenharmony_ci    if (ctx->secretValue != NULL) {
471e1051a39Sopenharmony_ci        OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
472e1051a39Sopenharmony_ci        ASN1_OCTET_STRING_free(ctx->secretValue);
473e1051a39Sopenharmony_ci    }
474e1051a39Sopenharmony_ci    ctx->secretValue = secretValue;
475e1051a39Sopenharmony_ci    return 1;
476e1051a39Sopenharmony_ci}
477e1051a39Sopenharmony_ci
478e1051a39Sopenharmony_ci/* Returns the cert chain computed by OSSL_CMP_certConf_cb(), NULL on error */
479e1051a39Sopenharmony_ciSTACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx)
480e1051a39Sopenharmony_ci{
481e1051a39Sopenharmony_ci    if (ctx == NULL) {
482e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
483e1051a39Sopenharmony_ci        return NULL;
484e1051a39Sopenharmony_ci    }
485e1051a39Sopenharmony_ci    return X509_chain_up_ref(ctx->newChain);
486e1051a39Sopenharmony_ci}
487e1051a39Sopenharmony_ci
488e1051a39Sopenharmony_ci/*
489e1051a39Sopenharmony_ci * Copies any given stack of inbound X509 certificates to newChain
490e1051a39Sopenharmony_ci * of the OSSL_CMP_CTX structure so that they may be retrieved later.
491e1051a39Sopenharmony_ci */
492e1051a39Sopenharmony_ciint ossl_cmp_ctx_set1_newChain(OSSL_CMP_CTX *ctx, STACK_OF(X509) *newChain)
493e1051a39Sopenharmony_ci{
494e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
495e1051a39Sopenharmony_ci        return 0;
496e1051a39Sopenharmony_ci
497e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->newChain, X509_free);
498e1051a39Sopenharmony_ci    ctx->newChain = NULL;
499e1051a39Sopenharmony_ci    return newChain == NULL ||
500e1051a39Sopenharmony_ci        (ctx->newChain = X509_chain_up_ref(newChain)) != NULL;
501e1051a39Sopenharmony_ci}
502e1051a39Sopenharmony_ci
503e1051a39Sopenharmony_ci/* Returns the stack of extraCerts received in CertRepMessage, NULL on error */
504e1051a39Sopenharmony_ciSTACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx)
505e1051a39Sopenharmony_ci{
506e1051a39Sopenharmony_ci    if (ctx == NULL) {
507e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
508e1051a39Sopenharmony_ci        return NULL;
509e1051a39Sopenharmony_ci    }
510e1051a39Sopenharmony_ci    return X509_chain_up_ref(ctx->extraCertsIn);
511e1051a39Sopenharmony_ci}
512e1051a39Sopenharmony_ci
513e1051a39Sopenharmony_ci/*
514e1051a39Sopenharmony_ci * Copies any given stack of inbound X509 certificates to extraCertsIn
515e1051a39Sopenharmony_ci * of the OSSL_CMP_CTX structure so that they may be retrieved later.
516e1051a39Sopenharmony_ci */
517e1051a39Sopenharmony_ciint ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
518e1051a39Sopenharmony_ci                                   STACK_OF(X509) *extraCertsIn)
519e1051a39Sopenharmony_ci{
520e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
521e1051a39Sopenharmony_ci        return 0;
522e1051a39Sopenharmony_ci
523e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->extraCertsIn, X509_free);
524e1051a39Sopenharmony_ci    ctx->extraCertsIn = NULL;
525e1051a39Sopenharmony_ci    return extraCertsIn == NULL
526e1051a39Sopenharmony_ci        || (ctx->extraCertsIn = X509_chain_up_ref(extraCertsIn)) != NULL;
527e1051a39Sopenharmony_ci}
528e1051a39Sopenharmony_ci
529e1051a39Sopenharmony_ci/*
530e1051a39Sopenharmony_ci * Copies any given stack as the new stack of X509
531e1051a39Sopenharmony_ci * certificates to send out in the extraCerts field.
532e1051a39Sopenharmony_ci */
533e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
534e1051a39Sopenharmony_ci                                    STACK_OF(X509) *extraCertsOut)
535e1051a39Sopenharmony_ci{
536e1051a39Sopenharmony_ci    if (ctx == NULL) {
537e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
538e1051a39Sopenharmony_ci        return 0;
539e1051a39Sopenharmony_ci    }
540e1051a39Sopenharmony_ci
541e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->extraCertsOut, X509_free);
542e1051a39Sopenharmony_ci    ctx->extraCertsOut = NULL;
543e1051a39Sopenharmony_ci    return extraCertsOut == NULL
544e1051a39Sopenharmony_ci        || (ctx->extraCertsOut = X509_chain_up_ref(extraCertsOut)) != NULL;
545e1051a39Sopenharmony_ci}
546e1051a39Sopenharmony_ci
547e1051a39Sopenharmony_ci/*
548e1051a39Sopenharmony_ci * Add the given policy info object
549e1051a39Sopenharmony_ci * to the X509_EXTENSIONS of the requested certificate template.
550e1051a39Sopenharmony_ci */
551e1051a39Sopenharmony_ciint OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
552e1051a39Sopenharmony_ci{
553e1051a39Sopenharmony_ci    if (ctx == NULL || pinfo == NULL) {
554e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
555e1051a39Sopenharmony_ci        return 0;
556e1051a39Sopenharmony_ci    }
557e1051a39Sopenharmony_ci
558e1051a39Sopenharmony_ci    if (ctx->policies == NULL
559e1051a39Sopenharmony_ci            && (ctx->policies = CERTIFICATEPOLICIES_new()) == NULL)
560e1051a39Sopenharmony_ci        return 0;
561e1051a39Sopenharmony_ci
562e1051a39Sopenharmony_ci    return sk_POLICYINFO_push(ctx->policies, pinfo);
563e1051a39Sopenharmony_ci}
564e1051a39Sopenharmony_ci
565e1051a39Sopenharmony_ci/* Add an ITAV for geninfo of the PKI message header */
566e1051a39Sopenharmony_ciint OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
567e1051a39Sopenharmony_ci{
568e1051a39Sopenharmony_ci    if (ctx == NULL) {
569e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
570e1051a39Sopenharmony_ci        return 0;
571e1051a39Sopenharmony_ci    }
572e1051a39Sopenharmony_ci    return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
573e1051a39Sopenharmony_ci}
574e1051a39Sopenharmony_ci
575e1051a39Sopenharmony_ciint OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx)
576e1051a39Sopenharmony_ci{
577e1051a39Sopenharmony_ci    if (ctx == NULL) {
578e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
579e1051a39Sopenharmony_ci        return 0;
580e1051a39Sopenharmony_ci    }
581e1051a39Sopenharmony_ci    OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs);
582e1051a39Sopenharmony_ci    ctx->geninfo_ITAVs = NULL;
583e1051a39Sopenharmony_ci    return 1;
584e1051a39Sopenharmony_ci}
585e1051a39Sopenharmony_ci
586e1051a39Sopenharmony_ci/* Add an itav for the body of outgoing general messages */
587e1051a39Sopenharmony_ciint OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
588e1051a39Sopenharmony_ci{
589e1051a39Sopenharmony_ci    if (ctx == NULL) {
590e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
591e1051a39Sopenharmony_ci        return 0;
592e1051a39Sopenharmony_ci    }
593e1051a39Sopenharmony_ci    return OSSL_CMP_ITAV_push0_stack_item(&ctx->genm_ITAVs, itav);
594e1051a39Sopenharmony_ci}
595e1051a39Sopenharmony_ci
596e1051a39Sopenharmony_ci/*
597e1051a39Sopenharmony_ci * Returns a duplicate of the stack of X509 certificates that
598e1051a39Sopenharmony_ci * were received in the caPubs field of the last CertRepMessage.
599e1051a39Sopenharmony_ci * Returns NULL on error
600e1051a39Sopenharmony_ci */
601e1051a39Sopenharmony_ciSTACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx)
602e1051a39Sopenharmony_ci{
603e1051a39Sopenharmony_ci    if (ctx == NULL) {
604e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
605e1051a39Sopenharmony_ci        return NULL;
606e1051a39Sopenharmony_ci    }
607e1051a39Sopenharmony_ci    return X509_chain_up_ref(ctx->caPubs);
608e1051a39Sopenharmony_ci}
609e1051a39Sopenharmony_ci
610e1051a39Sopenharmony_ci/*
611e1051a39Sopenharmony_ci * Copies any given stack of certificates to the given
612e1051a39Sopenharmony_ci * OSSL_CMP_CTX structure so that they may be retrieved later.
613e1051a39Sopenharmony_ci */
614e1051a39Sopenharmony_ciint ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs)
615e1051a39Sopenharmony_ci{
616e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
617e1051a39Sopenharmony_ci        return 0;
618e1051a39Sopenharmony_ci
619e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->caPubs, X509_free);
620e1051a39Sopenharmony_ci    ctx->caPubs = NULL;
621e1051a39Sopenharmony_ci    return caPubs == NULL || (ctx->caPubs = X509_chain_up_ref(caPubs)) != NULL;
622e1051a39Sopenharmony_ci}
623e1051a39Sopenharmony_ci
624e1051a39Sopenharmony_ci#define char_dup OPENSSL_strdup
625e1051a39Sopenharmony_ci#define char_free OPENSSL_free
626e1051a39Sopenharmony_ci#define DEFINE_OSSL_CMP_CTX_set1(FIELD, TYPE) /* this uses _dup */ \
627e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \
628e1051a39Sopenharmony_ci{ \
629e1051a39Sopenharmony_ci    TYPE *val_dup = NULL; \
630e1051a39Sopenharmony_ci    \
631e1051a39Sopenharmony_ci    if (ctx == NULL) { \
632e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
633e1051a39Sopenharmony_ci        return 0; \
634e1051a39Sopenharmony_ci    } \
635e1051a39Sopenharmony_ci    \
636e1051a39Sopenharmony_ci    if (val != NULL && (val_dup = TYPE##_dup(val)) == NULL) \
637e1051a39Sopenharmony_ci        return 0; \
638e1051a39Sopenharmony_ci    TYPE##_free(ctx->FIELD); \
639e1051a39Sopenharmony_ci    ctx->FIELD = val_dup; \
640e1051a39Sopenharmony_ci    return 1; \
641e1051a39Sopenharmony_ci}
642e1051a39Sopenharmony_ci
643e1051a39Sopenharmony_ci#define X509_invalid(cert) (!ossl_x509v3_cache_extensions(cert))
644e1051a39Sopenharmony_ci#define EVP_PKEY_invalid(key) 0
645e1051a39Sopenharmony_ci#define DEFINE_OSSL_CMP_CTX_set1_up_ref(FIELD, TYPE) \
646e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
647e1051a39Sopenharmony_ci{ \
648e1051a39Sopenharmony_ci    if (ctx == NULL) { \
649e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
650e1051a39Sopenharmony_ci        return 0; \
651e1051a39Sopenharmony_ci    } \
652e1051a39Sopenharmony_ci    \
653e1051a39Sopenharmony_ci    /* prevent misleading error later on malformed cert or provider issue */ \
654e1051a39Sopenharmony_ci    if (val != NULL && TYPE##_invalid(val)) { \
655e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE); \
656e1051a39Sopenharmony_ci        return 0; \
657e1051a39Sopenharmony_ci    } \
658e1051a39Sopenharmony_ci    if (val != NULL && !TYPE##_up_ref(val)) \
659e1051a39Sopenharmony_ci        return 0; \
660e1051a39Sopenharmony_ci    TYPE##_free(ctx->FIELD); \
661e1051a39Sopenharmony_ci    ctx->FIELD = val; \
662e1051a39Sopenharmony_ci    return 1; \
663e1051a39Sopenharmony_ci}
664e1051a39Sopenharmony_ci
665e1051a39Sopenharmony_ci/*
666e1051a39Sopenharmony_ci * Pins the server certificate to be directly trusted (even if it is expired)
667e1051a39Sopenharmony_ci * for verifying response messages.
668e1051a39Sopenharmony_ci * Cert pointer is not consumed. It may be NULL to clear the entry.
669e1051a39Sopenharmony_ci */
670e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509)
671e1051a39Sopenharmony_ci
672e1051a39Sopenharmony_ci/* Set the X509 name of the recipient to be placed in the PKIHeader */
673e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
674e1051a39Sopenharmony_ci
675e1051a39Sopenharmony_ci/* Store the X509 name of the expected sender in the PKIHeader of responses */
676e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
677e1051a39Sopenharmony_ci
678e1051a39Sopenharmony_ci/* Set the X509 name of the issuer to be placed in the certTemplate */
679e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
680e1051a39Sopenharmony_ci
681e1051a39Sopenharmony_ci/*
682e1051a39Sopenharmony_ci * Set the subject name that will be placed in the certificate
683e1051a39Sopenharmony_ci * request. This will be the subject name on the received certificate.
684e1051a39Sopenharmony_ci */
685e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
686e1051a39Sopenharmony_ci
687e1051a39Sopenharmony_ci/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
688e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
689e1051a39Sopenharmony_ci{
690e1051a39Sopenharmony_ci    if (ctx == NULL) {
691e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
692e1051a39Sopenharmony_ci        return 0;
693e1051a39Sopenharmony_ci    }
694e1051a39Sopenharmony_ci
695e1051a39Sopenharmony_ci    if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 && exts != NULL
696e1051a39Sopenharmony_ci            && X509v3_get_ext_by_NID(exts, NID_subject_alt_name, -1) >= 0) {
697e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES);
698e1051a39Sopenharmony_ci        return 0;
699e1051a39Sopenharmony_ci    }
700e1051a39Sopenharmony_ci    sk_X509_EXTENSION_pop_free(ctx->reqExtensions, X509_EXTENSION_free);
701e1051a39Sopenharmony_ci    ctx->reqExtensions = exts;
702e1051a39Sopenharmony_ci    return 1;
703e1051a39Sopenharmony_ci}
704e1051a39Sopenharmony_ci
705e1051a39Sopenharmony_ci/* returns 1 if ctx contains a Subject Alternative Name extension, else 0 */
706e1051a39Sopenharmony_ciint OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
707e1051a39Sopenharmony_ci{
708e1051a39Sopenharmony_ci    if (ctx == NULL) {
709e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
710e1051a39Sopenharmony_ci        return -1;
711e1051a39Sopenharmony_ci    }
712e1051a39Sopenharmony_ci    /* if one of the following conditions 'fail' this is not an error */
713e1051a39Sopenharmony_ci    return ctx->reqExtensions != NULL
714e1051a39Sopenharmony_ci        && X509v3_get_ext_by_NID(ctx->reqExtensions,
715e1051a39Sopenharmony_ci                                 NID_subject_alt_name, -1) >= 0;
716e1051a39Sopenharmony_ci}
717e1051a39Sopenharmony_ci
718e1051a39Sopenharmony_ci/*
719e1051a39Sopenharmony_ci * Add a GENERAL_NAME structure that will be added to the CRMF
720e1051a39Sopenharmony_ci * request's extensions field to request subject alternative names.
721e1051a39Sopenharmony_ci */
722e1051a39Sopenharmony_ciint OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
723e1051a39Sopenharmony_ci                                      const GENERAL_NAME *name)
724e1051a39Sopenharmony_ci{
725e1051a39Sopenharmony_ci    GENERAL_NAME *name_dup;
726e1051a39Sopenharmony_ci
727e1051a39Sopenharmony_ci    if (ctx == NULL || name == NULL) {
728e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
729e1051a39Sopenharmony_ci        return 0;
730e1051a39Sopenharmony_ci    }
731e1051a39Sopenharmony_ci
732e1051a39Sopenharmony_ci    if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) {
733e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES);
734e1051a39Sopenharmony_ci        return 0;
735e1051a39Sopenharmony_ci    }
736e1051a39Sopenharmony_ci
737e1051a39Sopenharmony_ci    if (ctx->subjectAltNames == NULL
738e1051a39Sopenharmony_ci            && (ctx->subjectAltNames = sk_GENERAL_NAME_new_null()) == NULL)
739e1051a39Sopenharmony_ci        return 0;
740e1051a39Sopenharmony_ci    if ((name_dup = GENERAL_NAME_dup(name)) == NULL)
741e1051a39Sopenharmony_ci        return 0;
742e1051a39Sopenharmony_ci    if (!sk_GENERAL_NAME_push(ctx->subjectAltNames, name_dup)) {
743e1051a39Sopenharmony_ci        GENERAL_NAME_free(name_dup);
744e1051a39Sopenharmony_ci        return 0;
745e1051a39Sopenharmony_ci    }
746e1051a39Sopenharmony_ci    return 1;
747e1051a39Sopenharmony_ci}
748e1051a39Sopenharmony_ci
749e1051a39Sopenharmony_ci/*
750e1051a39Sopenharmony_ci * Set our own client certificate, used for example in KUR and when
751e1051a39Sopenharmony_ci * doing the IR with existing certificate.
752e1051a39Sopenharmony_ci */
753e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509)
754e1051a39Sopenharmony_ci
755e1051a39Sopenharmony_ciint OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted,
756e1051a39Sopenharmony_ci                                  STACK_OF(X509) *candidates)
757e1051a39Sopenharmony_ci{
758e1051a39Sopenharmony_ci    STACK_OF(X509) *chain;
759e1051a39Sopenharmony_ci
760e1051a39Sopenharmony_ci    if (ctx == NULL) {
761e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
762e1051a39Sopenharmony_ci        return 0;
763e1051a39Sopenharmony_ci    }
764e1051a39Sopenharmony_ci
765e1051a39Sopenharmony_ci    if (!ossl_x509_add_certs_new(&ctx->untrusted, candidates,
766e1051a39Sopenharmony_ci                                 X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
767e1051a39Sopenharmony_ci        return 0;
768e1051a39Sopenharmony_ci
769e1051a39Sopenharmony_ci    ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert");
770e1051a39Sopenharmony_ci    chain = X509_build_chain(ctx->cert, ctx->untrusted, own_trusted, 0,
771e1051a39Sopenharmony_ci                             ctx->libctx, ctx->propq);
772e1051a39Sopenharmony_ci    if (chain == NULL) {
773e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN);
774e1051a39Sopenharmony_ci        return 0;
775e1051a39Sopenharmony_ci    }
776e1051a39Sopenharmony_ci    ossl_cmp_debug(ctx, "success building chain for own CMP signer cert");
777e1051a39Sopenharmony_ci    ctx->chain = chain;
778e1051a39Sopenharmony_ci    return 1;
779e1051a39Sopenharmony_ci}
780e1051a39Sopenharmony_ci
781e1051a39Sopenharmony_ci/*
782e1051a39Sopenharmony_ci * Set the old certificate that we are updating in KUR
783e1051a39Sopenharmony_ci * or the certificate to be revoked in RR, respectively.
784e1051a39Sopenharmony_ci * Also used as reference cert (defaulting to cert) for deriving subject DN
785e1051a39Sopenharmony_ci * and SANs. Its issuer is used as default recipient in the CMP message header.
786e1051a39Sopenharmony_ci */
787e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509)
788e1051a39Sopenharmony_ci
789e1051a39Sopenharmony_ci/* Set the PKCS#10 CSR to be sent in P10CR */
790e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
791e1051a39Sopenharmony_ci
792e1051a39Sopenharmony_ci/*
793e1051a39Sopenharmony_ci * Set the (newly received in IP/KUP/CP) certificate in the context.
794e1051a39Sopenharmony_ci * This only permits for one cert to be enrolled at a time.
795e1051a39Sopenharmony_ci */
796e1051a39Sopenharmony_ciint ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert)
797e1051a39Sopenharmony_ci{
798e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
799e1051a39Sopenharmony_ci        return 0;
800e1051a39Sopenharmony_ci
801e1051a39Sopenharmony_ci    X509_free(ctx->newCert);
802e1051a39Sopenharmony_ci    ctx->newCert = cert;
803e1051a39Sopenharmony_ci    return 1;
804e1051a39Sopenharmony_ci}
805e1051a39Sopenharmony_ci
806e1051a39Sopenharmony_ci/*
807e1051a39Sopenharmony_ci * Get the (newly received in IP/KUP/CP) client certificate from the context
808e1051a39Sopenharmony_ci * This only permits for one client cert to be received...
809e1051a39Sopenharmony_ci */
810e1051a39Sopenharmony_ciX509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx)
811e1051a39Sopenharmony_ci{
812e1051a39Sopenharmony_ci    if (ctx == NULL) {
813e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
814e1051a39Sopenharmony_ci        return NULL;
815e1051a39Sopenharmony_ci    }
816e1051a39Sopenharmony_ci    return ctx->newCert;
817e1051a39Sopenharmony_ci}
818e1051a39Sopenharmony_ci
819e1051a39Sopenharmony_ci/* Set the client's current private key */
820e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY)
821e1051a39Sopenharmony_ci
822e1051a39Sopenharmony_ci/* Set new key pair. Used e.g. when doing Key Update */
823e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
824e1051a39Sopenharmony_ci{
825e1051a39Sopenharmony_ci    if (ctx == NULL) {
826e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
827e1051a39Sopenharmony_ci        return 0;
828e1051a39Sopenharmony_ci    }
829e1051a39Sopenharmony_ci
830e1051a39Sopenharmony_ci    EVP_PKEY_free(ctx->newPkey);
831e1051a39Sopenharmony_ci    ctx->newPkey = pkey;
832e1051a39Sopenharmony_ci    ctx->newPkey_priv = priv;
833e1051a39Sopenharmony_ci    return 1;
834e1051a39Sopenharmony_ci}
835e1051a39Sopenharmony_ci
836e1051a39Sopenharmony_ci/* Get the private/public key to use for cert enrollment, or NULL on error */
837e1051a39Sopenharmony_ci/* In case |priv| == 0, better use ossl_cmp_ctx_get0_newPubkey() below */
838e1051a39Sopenharmony_ciEVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
839e1051a39Sopenharmony_ci{
840e1051a39Sopenharmony_ci    if (ctx == NULL) {
841e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
842e1051a39Sopenharmony_ci        return NULL;
843e1051a39Sopenharmony_ci    }
844e1051a39Sopenharmony_ci
845e1051a39Sopenharmony_ci    if (ctx->newPkey != NULL)
846e1051a39Sopenharmony_ci        return priv && !ctx->newPkey_priv ? NULL : ctx->newPkey;
847e1051a39Sopenharmony_ci    if (ctx->p10CSR != NULL)
848e1051a39Sopenharmony_ci        return priv ? NULL : X509_REQ_get0_pubkey(ctx->p10CSR);
849e1051a39Sopenharmony_ci    return ctx->pkey; /* may be NULL */
850e1051a39Sopenharmony_ci}
851e1051a39Sopenharmony_ci
852e1051a39Sopenharmony_ciEVP_PKEY *ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX *ctx)
853e1051a39Sopenharmony_ci{
854e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
855e1051a39Sopenharmony_ci        return NULL;
856e1051a39Sopenharmony_ci    if (ctx->newPkey != NULL)
857e1051a39Sopenharmony_ci        return ctx->newPkey;
858e1051a39Sopenharmony_ci    if (ctx->p10CSR != NULL)
859e1051a39Sopenharmony_ci        return X509_REQ_get0_pubkey(ctx->p10CSR);
860e1051a39Sopenharmony_ci    if (ctx->oldCert != NULL)
861e1051a39Sopenharmony_ci        return X509_get0_pubkey(ctx->oldCert);
862e1051a39Sopenharmony_ci    if (ctx->cert != NULL)
863e1051a39Sopenharmony_ci        return X509_get0_pubkey(ctx->cert);
864e1051a39Sopenharmony_ci    return ctx->pkey;
865e1051a39Sopenharmony_ci}
866e1051a39Sopenharmony_ci
867e1051a39Sopenharmony_ci/* Set the given transactionID to the context */
868e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
869e1051a39Sopenharmony_ci                                    const ASN1_OCTET_STRING *id)
870e1051a39Sopenharmony_ci{
871e1051a39Sopenharmony_ci    if (ctx == NULL) {
872e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
873e1051a39Sopenharmony_ci        return 0;
874e1051a39Sopenharmony_ci    }
875e1051a39Sopenharmony_ci    return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id);
876e1051a39Sopenharmony_ci}
877e1051a39Sopenharmony_ci
878e1051a39Sopenharmony_ci/* Set the nonce to be used for the recipNonce in the message created next */
879e1051a39Sopenharmony_ciint ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
880e1051a39Sopenharmony_ci                                 const ASN1_OCTET_STRING *nonce)
881e1051a39Sopenharmony_ci{
882e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
883e1051a39Sopenharmony_ci        return 0;
884e1051a39Sopenharmony_ci    return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce);
885e1051a39Sopenharmony_ci}
886e1051a39Sopenharmony_ci
887e1051a39Sopenharmony_ci/* Stores the given nonce as the last senderNonce sent out */
888e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
889e1051a39Sopenharmony_ci                                  const ASN1_OCTET_STRING *nonce)
890e1051a39Sopenharmony_ci{
891e1051a39Sopenharmony_ci    if (ctx == NULL) {
892e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
893e1051a39Sopenharmony_ci        return 0;
894e1051a39Sopenharmony_ci    }
895e1051a39Sopenharmony_ci    return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce);
896e1051a39Sopenharmony_ci}
897e1051a39Sopenharmony_ci
898e1051a39Sopenharmony_ci/* Set the proxy server to use for HTTP(S) connections */
899e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(proxy, char)
900e1051a39Sopenharmony_ci
901e1051a39Sopenharmony_ci/* Set the (HTTP) host name of the CMP server */
902e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(server, char)
903e1051a39Sopenharmony_ci
904e1051a39Sopenharmony_ci/* Set the server exclusion list of the HTTP proxy server */
905e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
906e1051a39Sopenharmony_ci
907e1051a39Sopenharmony_ci/* Set the http connect/disconnect callback function to be used for HTTP(S) */
908e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
909e1051a39Sopenharmony_ci{
910e1051a39Sopenharmony_ci    if (ctx == NULL) {
911e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
912e1051a39Sopenharmony_ci        return 0;
913e1051a39Sopenharmony_ci    }
914e1051a39Sopenharmony_ci    ctx->http_cb = cb;
915e1051a39Sopenharmony_ci    return 1;
916e1051a39Sopenharmony_ci}
917e1051a39Sopenharmony_ci
918e1051a39Sopenharmony_ci/* Set argument optionally to be used by the http connect/disconnect callback */
919e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
920e1051a39Sopenharmony_ci{
921e1051a39Sopenharmony_ci    if (ctx == NULL) {
922e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
923e1051a39Sopenharmony_ci        return 0;
924e1051a39Sopenharmony_ci    }
925e1051a39Sopenharmony_ci    ctx->http_cb_arg = arg;
926e1051a39Sopenharmony_ci    return 1;
927e1051a39Sopenharmony_ci}
928e1051a39Sopenharmony_ci
929e1051a39Sopenharmony_ci/*
930e1051a39Sopenharmony_ci * Get argument optionally to be used by the http connect/disconnect callback
931e1051a39Sopenharmony_ci * Returns callback argument set previously (NULL if not set or on error)
932e1051a39Sopenharmony_ci */
933e1051a39Sopenharmony_civoid *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx)
934e1051a39Sopenharmony_ci{
935e1051a39Sopenharmony_ci    if (ctx == NULL) {
936e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
937e1051a39Sopenharmony_ci        return NULL;
938e1051a39Sopenharmony_ci    }
939e1051a39Sopenharmony_ci    return ctx->http_cb_arg;
940e1051a39Sopenharmony_ci}
941e1051a39Sopenharmony_ci
942e1051a39Sopenharmony_ci/* Set callback function for sending CMP request and receiving response */
943e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
944e1051a39Sopenharmony_ci{
945e1051a39Sopenharmony_ci    if (ctx == NULL) {
946e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
947e1051a39Sopenharmony_ci        return 0;
948e1051a39Sopenharmony_ci    }
949e1051a39Sopenharmony_ci    ctx->transfer_cb = cb;
950e1051a39Sopenharmony_ci    return 1;
951e1051a39Sopenharmony_ci}
952e1051a39Sopenharmony_ci
953e1051a39Sopenharmony_ci/* Set argument optionally to be used by the transfer callback */
954e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
955e1051a39Sopenharmony_ci{
956e1051a39Sopenharmony_ci    if (ctx == NULL) {
957e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
958e1051a39Sopenharmony_ci        return 0;
959e1051a39Sopenharmony_ci    }
960e1051a39Sopenharmony_ci    ctx->transfer_cb_arg = arg;
961e1051a39Sopenharmony_ci    return 1;
962e1051a39Sopenharmony_ci}
963e1051a39Sopenharmony_ci
964e1051a39Sopenharmony_ci/*
965e1051a39Sopenharmony_ci * Get argument optionally to be used by the transfer callback.
966e1051a39Sopenharmony_ci * Returns callback argument set previously (NULL if not set or on error)
967e1051a39Sopenharmony_ci */
968e1051a39Sopenharmony_civoid *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx)
969e1051a39Sopenharmony_ci{
970e1051a39Sopenharmony_ci    if (ctx == NULL) {
971e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
972e1051a39Sopenharmony_ci        return NULL;
973e1051a39Sopenharmony_ci    }
974e1051a39Sopenharmony_ci    return ctx->transfer_cb_arg;
975e1051a39Sopenharmony_ci}
976e1051a39Sopenharmony_ci
977e1051a39Sopenharmony_ci/** Set the HTTP server port to be used */
978e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
979e1051a39Sopenharmony_ci{
980e1051a39Sopenharmony_ci    if (ctx == NULL) {
981e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
982e1051a39Sopenharmony_ci        return 0;
983e1051a39Sopenharmony_ci    }
984e1051a39Sopenharmony_ci    ctx->serverPort = port;
985e1051a39Sopenharmony_ci    return 1;
986e1051a39Sopenharmony_ci}
987e1051a39Sopenharmony_ci
988e1051a39Sopenharmony_ci/* Set the HTTP path to be used on the server (e.g "pkix/") */
989e1051a39Sopenharmony_ciDEFINE_OSSL_CMP_CTX_set1(serverPath, char)
990e1051a39Sopenharmony_ci
991e1051a39Sopenharmony_ci/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
992e1051a39Sopenharmony_ciint ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info)
993e1051a39Sopenharmony_ci{
994e1051a39Sopenharmony_ci    if (!ossl_assert(ctx != NULL))
995e1051a39Sopenharmony_ci        return 0;
996e1051a39Sopenharmony_ci    ctx->failInfoCode = fail_info;
997e1051a39Sopenharmony_ci    return 1;
998e1051a39Sopenharmony_ci}
999e1051a39Sopenharmony_ci
1000e1051a39Sopenharmony_ci/*
1001e1051a39Sopenharmony_ci * Get the failInfo error code in OSSL_CMP_CTX as bit encoding.
1002e1051a39Sopenharmony_ci * Returns bit string as integer on success, -1 on error
1003e1051a39Sopenharmony_ci */
1004e1051a39Sopenharmony_ciint OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
1005e1051a39Sopenharmony_ci{
1006e1051a39Sopenharmony_ci    if (ctx == NULL) {
1007e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1008e1051a39Sopenharmony_ci        return -1;
1009e1051a39Sopenharmony_ci    }
1010e1051a39Sopenharmony_ci    return ctx->failInfoCode;
1011e1051a39Sopenharmony_ci}
1012e1051a39Sopenharmony_ci
1013e1051a39Sopenharmony_ci/* Set a Boolean or integer option of the context to the "val" arg */
1014e1051a39Sopenharmony_ciint OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
1015e1051a39Sopenharmony_ci{
1016e1051a39Sopenharmony_ci    int min_val;
1017e1051a39Sopenharmony_ci
1018e1051a39Sopenharmony_ci    if (ctx == NULL) {
1019e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1020e1051a39Sopenharmony_ci        return 0;
1021e1051a39Sopenharmony_ci    }
1022e1051a39Sopenharmony_ci
1023e1051a39Sopenharmony_ci    switch (opt) {
1024e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_REVOCATION_REASON:
1025e1051a39Sopenharmony_ci        min_val = OCSP_REVOKED_STATUS_NOSTATUS;
1026e1051a39Sopenharmony_ci        break;
1027e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_POPO_METHOD:
1028e1051a39Sopenharmony_ci        min_val = OSSL_CRMF_POPO_NONE;
1029e1051a39Sopenharmony_ci        break;
1030e1051a39Sopenharmony_ci    default:
1031e1051a39Sopenharmony_ci        min_val = 0;
1032e1051a39Sopenharmony_ci        break;
1033e1051a39Sopenharmony_ci    }
1034e1051a39Sopenharmony_ci    if (val < min_val) {
1035e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_SMALL);
1036e1051a39Sopenharmony_ci        return 0;
1037e1051a39Sopenharmony_ci    }
1038e1051a39Sopenharmony_ci
1039e1051a39Sopenharmony_ci    switch (opt) {
1040e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_LOG_VERBOSITY:
1041e1051a39Sopenharmony_ci        if (val > OSSL_CMP_LOG_MAX) {
1042e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
1043e1051a39Sopenharmony_ci            return 0;
1044e1051a39Sopenharmony_ci        }
1045e1051a39Sopenharmony_ci        ctx->log_verbosity = val;
1046e1051a39Sopenharmony_ci        break;
1047e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
1048e1051a39Sopenharmony_ci        ctx->implicitConfirm = val;
1049e1051a39Sopenharmony_ci        break;
1050e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_DISABLE_CONFIRM:
1051e1051a39Sopenharmony_ci        ctx->disableConfirm = val;
1052e1051a39Sopenharmony_ci        break;
1053e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_UNPROTECTED_SEND:
1054e1051a39Sopenharmony_ci        ctx->unprotectedSend = val;
1055e1051a39Sopenharmony_ci        break;
1056e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
1057e1051a39Sopenharmony_ci        ctx->unprotectedErrors = val;
1058e1051a39Sopenharmony_ci        break;
1059e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_VALIDITY_DAYS:
1060e1051a39Sopenharmony_ci        ctx->days = val;
1061e1051a39Sopenharmony_ci        break;
1062e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
1063e1051a39Sopenharmony_ci        ctx->SubjectAltName_nodefault = val;
1064e1051a39Sopenharmony_ci        break;
1065e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL:
1066e1051a39Sopenharmony_ci        ctx->setSubjectAltNameCritical = val;
1067e1051a39Sopenharmony_ci        break;
1068e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_POLICIES_CRITICAL:
1069e1051a39Sopenharmony_ci        ctx->setPoliciesCritical = val;
1070e1051a39Sopenharmony_ci        break;
1071e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
1072e1051a39Sopenharmony_ci        ctx->ignore_keyusage = val;
1073e1051a39Sopenharmony_ci        break;
1074e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_POPO_METHOD:
1075e1051a39Sopenharmony_ci        if (val > OSSL_CRMF_POPO_KEYAGREE) {
1076e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
1077e1051a39Sopenharmony_ci            return 0;
1078e1051a39Sopenharmony_ci        }
1079e1051a39Sopenharmony_ci        ctx->popoMethod = val;
1080e1051a39Sopenharmony_ci        break;
1081e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_DIGEST_ALGNID:
1082e1051a39Sopenharmony_ci        if (!cmp_ctx_set_md(ctx, &ctx->digest, val))
1083e1051a39Sopenharmony_ci            return 0;
1084e1051a39Sopenharmony_ci        break;
1085e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_OWF_ALGNID:
1086e1051a39Sopenharmony_ci        if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val))
1087e1051a39Sopenharmony_ci            return 0;
1088e1051a39Sopenharmony_ci        break;
1089e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_MAC_ALGNID:
1090e1051a39Sopenharmony_ci        ctx->pbm_mac = val;
1091e1051a39Sopenharmony_ci        break;
1092e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_KEEP_ALIVE:
1093e1051a39Sopenharmony_ci        ctx->keep_alive = val;
1094e1051a39Sopenharmony_ci        break;
1095e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_MSG_TIMEOUT:
1096e1051a39Sopenharmony_ci        ctx->msg_timeout = val;
1097e1051a39Sopenharmony_ci        break;
1098e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_TOTAL_TIMEOUT:
1099e1051a39Sopenharmony_ci        ctx->total_timeout = val;
1100e1051a39Sopenharmony_ci        break;
1101e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
1102e1051a39Sopenharmony_ci        ctx->permitTAInExtraCertsForIR = val;
1103e1051a39Sopenharmony_ci        break;
1104e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_REVOCATION_REASON:
1105e1051a39Sopenharmony_ci        if (val > OCSP_REVOKED_STATUS_AACOMPROMISE) {
1106e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
1107e1051a39Sopenharmony_ci            return 0;
1108e1051a39Sopenharmony_ci        }
1109e1051a39Sopenharmony_ci        ctx->revocationReason = val;
1110e1051a39Sopenharmony_ci        break;
1111e1051a39Sopenharmony_ci    default:
1112e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION);
1113e1051a39Sopenharmony_ci        return 0;
1114e1051a39Sopenharmony_ci    }
1115e1051a39Sopenharmony_ci
1116e1051a39Sopenharmony_ci    return 1;
1117e1051a39Sopenharmony_ci}
1118e1051a39Sopenharmony_ci
1119e1051a39Sopenharmony_ci/*
1120e1051a39Sopenharmony_ci * Reads a Boolean or integer option value from the context.
1121e1051a39Sopenharmony_ci * Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON)
1122e1051a39Sopenharmony_ci */
1123e1051a39Sopenharmony_ciint OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
1124e1051a39Sopenharmony_ci{
1125e1051a39Sopenharmony_ci    if (ctx == NULL) {
1126e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
1127e1051a39Sopenharmony_ci        return -1;
1128e1051a39Sopenharmony_ci    }
1129e1051a39Sopenharmony_ci
1130e1051a39Sopenharmony_ci    switch (opt) {
1131e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_LOG_VERBOSITY:
1132e1051a39Sopenharmony_ci        return ctx->log_verbosity;
1133e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
1134e1051a39Sopenharmony_ci        return ctx->implicitConfirm;
1135e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_DISABLE_CONFIRM:
1136e1051a39Sopenharmony_ci        return ctx->disableConfirm;
1137e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_UNPROTECTED_SEND:
1138e1051a39Sopenharmony_ci        return ctx->unprotectedSend;
1139e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
1140e1051a39Sopenharmony_ci        return ctx->unprotectedErrors;
1141e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_VALIDITY_DAYS:
1142e1051a39Sopenharmony_ci        return ctx->days;
1143e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
1144e1051a39Sopenharmony_ci        return ctx->SubjectAltName_nodefault;
1145e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL:
1146e1051a39Sopenharmony_ci        return ctx->setSubjectAltNameCritical;
1147e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_POLICIES_CRITICAL:
1148e1051a39Sopenharmony_ci        return ctx->setPoliciesCritical;
1149e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
1150e1051a39Sopenharmony_ci        return ctx->ignore_keyusage;
1151e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_POPO_METHOD:
1152e1051a39Sopenharmony_ci        return ctx->popoMethod;
1153e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_DIGEST_ALGNID:
1154e1051a39Sopenharmony_ci        return EVP_MD_get_type(ctx->digest);
1155e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_OWF_ALGNID:
1156e1051a39Sopenharmony_ci        return EVP_MD_get_type(ctx->pbm_owf);
1157e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_MAC_ALGNID:
1158e1051a39Sopenharmony_ci        return ctx->pbm_mac;
1159e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_KEEP_ALIVE:
1160e1051a39Sopenharmony_ci        return ctx->keep_alive;
1161e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_MSG_TIMEOUT:
1162e1051a39Sopenharmony_ci        return ctx->msg_timeout;
1163e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_TOTAL_TIMEOUT:
1164e1051a39Sopenharmony_ci        return ctx->total_timeout;
1165e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
1166e1051a39Sopenharmony_ci        return ctx->permitTAInExtraCertsForIR;
1167e1051a39Sopenharmony_ci    case OSSL_CMP_OPT_REVOCATION_REASON:
1168e1051a39Sopenharmony_ci        return ctx->revocationReason;
1169e1051a39Sopenharmony_ci    default:
1170e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION);
1171e1051a39Sopenharmony_ci        return -1;
1172e1051a39Sopenharmony_ci    }
1173e1051a39Sopenharmony_ci}
1174