/*
* 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
*/
/* CMP functions for PKIMessage construction */
#include "cmp_local.h"
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h>
#include <openssl/x509.h>
DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS)
DEFINE_STACK_OF(OSSL_CMP_ITAV)
DEFINE_STACK_OF(GENERAL_NAME)
DEFINE_STACK_OF(X509_EXTENSION)
DEFINE_STACK_OF(OSSL_CMP_PKISI)
DEFINE_STACK_OF(OSSL_CRMF_MSG)
DEFINE_STACK_OF(OSSL_CMP_CERTRESPONSE)
DEFINE_STACK_OF(OSSL_CRMF_CERTID)
DEFINE_STACK_OF(ASN1_UTF8STRING)
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg)
{
if (msg == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return NULL;
}
return msg->header;
}
const char *ossl_cmp_bodytype_to_string(int type)
{
static const char *type_names[] = {
"IR", "IP", "CR", "CP", "P10CR",
"POPDECC", "POPDECR", "KUR", "KUP",
"KRR", "KRP", "RR", "RP", "CCR", "CCP",
"CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
"GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
};
if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX)
return "illegal body type";
return type_names[type];
}
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type)
{
if (!ossl_assert(msg != NULL && msg->body != NULL))
return 0;
msg->body->type = type;
return 1;
}
int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg)
{
if (!ossl_assert(msg != NULL && msg->body != NULL))
return -1;
return msg->body->type;
}
/* Add an extension to the referenced extension stack, which may be NULL */
static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex)
{
X509_EXTENSION *ext;
int res;
if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */
return 0;
if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL)
return 0;
res = X509v3_add_ext(pexts, ext, 0) != NULL;
X509_EXTENSION_free(ext);
return res;
}
/* Add a CRL revocation reason code to extension stack, which may be NULL */
static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code)
{
ASN1_ENUMERATED *val = ASN1_ENUMERATED_new();
int res = 0;
if (val != NULL && ASN1_ENUMERATED_set(val, reason_code))
res = add1_extension(pexts, NID_crl_reason, 0 /* non-critical */, val);
ASN1_ENUMERATED_free(val);
return res;
}
OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype)
{
OSSL_CMP_MSG *msg = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
if ((msg = OSSL_CMP_MSG_new()) == NULL)
return NULL;
if (!ossl_cmp_hdr_init(ctx, msg->header)
|| !ossl_cmp_msg_set_bodytype(msg, bodytype))
goto err;
if (ctx->geninfo_ITAVs != NULL
&& !ossl_cmp_hdr_generalInfo_push1_items(msg->header,
ctx->geninfo_ITAVs))
goto err;
switch (bodytype) {
case OSSL_CMP_PKIBODY_IR:
case OSSL_CMP_PKIBODY_CR:
case OSSL_CMP_PKIBODY_KUR:
if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL)