/*
* Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Nokia 2007-2019
* Copyright Siemens AG 2015-2019
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/trace.h>
#include <openssl/bio.h>
#include <openssl/ocsp.h> /* for OCSP_REVOKED_STATUS_* */
#include "cmp_local.h"
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h>
DEFINE_STACK_OF(X509)
DEFINE_STACK_OF(X509_EXTENSION)
DEFINE_STACK_OF(POLICYINFO)
DEFINE_STACK_OF(ASN1_UTF8STRING)
DEFINE_STACK_OF(GENERAL_NAME)
DEFINE_STACK_OF(OSSL_CMP_ITAV)
/*
* Get current certificate store containing trusted root CA certs
*/
X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
{
if (ctx == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return NULL;
}
return ctx->trusted;
}
/*
* Set certificate store containing trusted (root) CA certs and possibly CRLs
* and a cert verification callback function used for CMP server authentication.
* Any already existing store entry is freed. Given NULL, the entry is reset.
*/
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
{
if (ctx == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return 0;
}
X509_STORE_free(ctx->trusted);
ctx->trusted = store;
return 1;
}
/* Get current list of non-trusted intermediate certs */
STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
{
if (ctx == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return NULL;
}
return ctx->untrusted_certs;
}
/*
* Set untrusted certificates for path construction in authentication of
* the CMP server and potentially others (TLS server, newly enrolled cert).
*/
int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
{
STACK_OF(X509) *untrusted_certs;
if (ctx == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return 0;
}
if ((untrusted_certs = sk_X509_new_null()) == NULL)
return 0;
if (X509_add_certs(untrusted_certs, certs,
X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP) != 1)
goto err;
sk_X509_pop_free(ctx->untrusted_certs, X509_free);
ctx->untrusted_certs = untrusted_certs;
return 1;
err:
sk_X509_pop_free(untrusted_certs, X509_free);
return 0;
}
/*
* Allocates and initializes OSSL_CMP_CTX context structure with default values.
* Returns new context on success, NULL on error
*/
OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
{
OSSL_CMP_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx == NULL)
return NULL;
ctx->log_verbosity = OSSL_CMP_LOG_INFO;
ctx->status = -1;
ctx->failInfoCode = -1;
ctx->msg_timeout = 2 * 60;
if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
goto err;
ctx->pbm_slen = 16;
ctx->pbm_owf = NID_sha256;
ctx->pbm_itercnt = 500;
ctx->pbm_mac = NID_hmac_sha1;
ctx->digest = NID_sha256;
ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE;
ctx->revocationReason = CRL_REASON_NONE;
/* all other elements are initialized to 0 or NULL, respectively */
return ctx;
err:
OSSL_CMP_CTX_free(ctx);
return NULL;
}
/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
{
if (ctx == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return 0;
}
ctx->status = -1;
ctx->failInfoCode = -1;
return ossl_cmp_ctx_set0_statusString(ctx, NULL)
&& ossl_cmp_ctx_set0_newCert(ctx, NULL)
&& ossl_cmp_ctx_set1_caPubs(ctx, NULL)
&&