$OPENSSLSRC=$OPENSSLSRC \
dhparam.c dsa.c dsaparam.c gendsa.c rsa.c rsautl.c genrsa.c
ENDIF
+IF[{- !$disabled{'cmp'} -}]
+ $OPENSSLSRC=$OPENSSLSRC cmp_mock_srv.c
+ENDIF
IF[{- !$disabled{apps} -}]
PROGRAMS=openssl
--- /dev/null
+/*
+ * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright Siemens AG 2018-2020
+ *
+ * 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 atf
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "apps.h"
+#include "cmp_mock_srv.h"
+
+#include <openssl/cmp.h>
+#include <openssl/err.h>
+#include <openssl/cmperr.h>
+
+/* the context for the CMP mock server */
+typedef struct
+{
+ X509 *certOut; /* certificate to be returned in cp/ip/kup msg */
+ STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */
+ STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
+ OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
+ int sendError; /* send error response also on valid requests */
+ OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */
+ int certReqId; /* id of last ir/cr/kur, used for polling */
+ int pollCount; /* number of polls before actual cert response */
+ int checkAfterTime; /* time the client should wait between polling */
+} mock_srv_ctx;
+
+
+static void mock_srv_ctx_free(mock_srv_ctx *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ OSSL_CMP_PKISI_free(ctx->statusOut);
+ X509_free(ctx->certOut);
+ sk_X509_pop_free(ctx->chainOut, X509_free);
+ sk_X509_pop_free(ctx->caPubsOut, X509_free);
+ OSSL_CMP_MSG_free(ctx->certReq);
+ OPENSSL_free(ctx);
+}
+
+static mock_srv_ctx *mock_srv_ctx_new(void)
+{
+ mock_srv_ctx *ctx = OPENSSL_zalloc(sizeof(mock_srv_ctx));
+
+ if (ctx == NULL)
+ goto err;
+
+ if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL)
+ goto err;
+
+ ctx->certReqId = -1;
+
+ /* all other elements are initialized to 0 or NULL, respectively */
+ return ctx;
+ err:
+ mock_srv_ctx_free(ctx);
+ return NULL;
+}
+
+int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (cert == NULL || X509_up_ref(cert)) {
+ X509_free(ctx->certOut);
+ ctx->certOut = cert;
+ return 1;
+ }
+ return 0;
+}
+
+int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *chain)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ STACK_OF(X509) *chain_copy = NULL;
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL)
+ return 0;
+ sk_X509_pop_free(ctx->chainOut, X509_free);
+ ctx->chainOut = chain_copy;
+ return 1;
+}
+
+int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *caPubs)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ STACK_OF(X509) *caPubs_copy = NULL;
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL)
+ return 0;
+ sk_X509_pop_free(ctx->caPubsOut, X509_free);
+ ctx->caPubsOut = caPubs_copy;
+ return 1;
+}
+
+int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
+ int fail_info, const char *text)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ OSSL_CMP_PKISI *si;
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, text)) == NULL)
+ return 0;
+ OSSL_CMP_PKISI_free(ctx->statusOut);
+ ctx->statusOut = si;
+ return 1;
+}
+
+int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ ctx->sendError = val != 0;
+ return 1;
+}
+
+int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (count < 0) {
+ CMPerr(0, CMP_R_INVALID_ARGS);
+ return 0;
+ }
+ ctx->pollCount = count;
+ return 1;
+}
+
+int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ ctx->checkAfterTime = sec;
+ return 1;
+}
+
+static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *cert_req,
+ int certReqId,
+ const OSSL_CRMF_MSG *crm,
+ const X509_REQ *p10cr,
+ X509 **certOut,
+ STACK_OF(X509) **chainOut,
+ STACK_OF(X509) **caPubs)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ OSSL_CMP_PKISI *si = NULL;
+
+ if (ctx == NULL || cert_req == NULL
+ || certOut == NULL || chainOut == NULL || caPubs == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+ if (ctx->sendError) {
+ CMPerr(0, CMP_R_ERROR_PROCESSING_MSG);
+ return NULL;
+ }
+
+ *certOut = NULL;
+ *chainOut = NULL;
+ *caPubs = NULL;
+ ctx->certReqId = certReqId;
+ if (ctx->pollCount > 0) {
+ ctx->pollCount--;
+ OSSL_CMP_MSG_free(ctx->certReq);
+ if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL)
+ return NULL;
+ return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
+ }
+ if (ctx->certOut != NULL
+ && (*certOut = X509_dup(ctx->certOut)) == NULL)
+ goto err;
+ if (ctx->chainOut != NULL
+ && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
+ goto err;
+ if (ctx->caPubsOut != NULL
+ && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL)
+ goto err;
+ if (ctx->statusOut != NULL
+ && (si = OSSL_CMP_PKISI_dup(ctx->statusOut)) == NULL)
+ goto err;
+ return si;
+
+ err:
+ X509_free(*certOut);
+ *certOut = NULL;
+ sk_X509_pop_free(*chainOut, X509_free);
+ *chainOut = NULL;
+ sk_X509_pop_free(*caPubs, X509_free);
+ *caPubs = NULL;
+ return NULL;
+}
+
+static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *rr,
+ const X509_NAME *issuer,
+ const ASN1_INTEGER *serial)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL || rr == NULL || issuer == NULL || serial == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+ if (ctx->sendError || ctx->certOut == NULL) {
+ CMPerr(0, CMP_R_ERROR_PROCESSING_MSG);
+ return NULL;
+ }
+
+ /* accept revocation only for the certificate we sent in ir/cr/kur */
+ if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0
+ || ASN1_INTEGER_cmp(serial,
+ X509_get0_serialNumber(ctx->certOut)) != 0) {
+ CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED);
+ return NULL;
+ }
+ return OSSL_CMP_PKISI_dup(ctx->statusOut);
+}
+
+static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *genm,
+ const STACK_OF(OSSL_CMP_ITAV) *in,
+ STACK_OF(OSSL_CMP_ITAV) **out)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL || genm == NULL || in == NULL || out == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (ctx->sendError) {
+ CMPerr(0, CMP_R_ERROR_PROCESSING_MSG);
+ return 0;
+ }
+
+ *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup,
+ OSSL_CMP_ITAV_free);
+ return *out != NULL;
+}
+
+static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
+ const OSSL_CMP_PKISI *statusInfo,
+ const ASN1_INTEGER *errorCode,
+ const OSSL_CMP_PKIFREETEXT *errorDetails)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ char buf[OSSL_CMP_PKISI_BUFLEN];
+ char *sibuf;
+ int i;
+
+ if (ctx == NULL || error == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return;
+ }
+
+ BIO_printf(bio_err, "mock server received error:\n");
+
+ if (statusInfo == NULL) {
+ BIO_printf(bio_err, "pkiStatusInfo absent\n");
+ } else {
+ sibuf = OSSL_CMP_snprint_PKIStatusInfo(statusInfo, buf, sizeof(buf));
+ BIO_printf(bio_err, "pkiStatusInfo: %s\n",
+ sibuf != NULL ? sibuf: "<invalid>");
+ }
+
+ if (errorCode == NULL)
+ BIO_printf(bio_err, "errorCode absent\n");
+ else
+ BIO_printf(bio_err, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode));
+
+ if (sk_ASN1_UTF8STRING_num(errorDetails) <= 0) {
+ BIO_printf(bio_err, "errorDetails absent\n");
+ } else {
+ BIO_printf(bio_err, "errorDetails: ");
+ for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) {
+ if (i > 0)
+ BIO_printf(bio_err, ", ");
+ BIO_printf(bio_err, "\"");
+ ASN1_STRING_print(bio_err,
+ sk_ASN1_UTF8STRING_value(errorDetails, i));
+ BIO_printf(bio_err, "\"");
+ }
+ BIO_printf(bio_err, "\n");
+ }
+}
+
+static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *certConf, int certReqId,
+ const ASN1_OCTET_STRING *certHash,
+ const OSSL_CMP_PKISI *si)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+ ASN1_OCTET_STRING *digest;
+
+ if (ctx == NULL || certConf == NULL || certHash == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (ctx->sendError || ctx->certOut == NULL) {
+ CMPerr(0, CMP_R_ERROR_PROCESSING_MSG);
+ return 0;
+ }
+
+ if (certReqId != ctx->certReqId) {
+ /* in case of error, invalid reqId -1 */
+ CMPerr(0, CMP_R_BAD_REQUEST_ID);
+ return 0;
+ }
+
+ if ((digest = OSSL_CMP_X509_digest(ctx->certOut)) == NULL)
+ return 0;
+ if (ASN1_OCTET_STRING_cmp(certHash, digest) != 0) {
+ ASN1_OCTET_STRING_free(digest);
+ CMPerr(0, CMP_R_CERTHASH_UNMATCHED);
+ return 0;
+ }
+ ASN1_OCTET_STRING_free(digest);
+ return 1;
+}
+
+static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *pollReq, int certReqId,
+ OSSL_CMP_MSG **certReq, int64_t *check_after)
+{
+ mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+ if (ctx == NULL || pollReq == NULL
+ || certReq == NULL || check_after == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ if (ctx->sendError || ctx->certReq == NULL) {
+ *certReq = NULL;
+ CMPerr(0, CMP_R_ERROR_PROCESSING_MSG);
+ return 0;
+ }
+
+ if (ctx->pollCount == 0) {
+ *certReq = ctx->certReq;
+ ctx->certReq = NULL;
+ *check_after = 0;
+ } else {
+ ctx->pollCount--;
+ *certReq = NULL;
+ *check_after = ctx->checkAfterTime;
+ }
+ return 1;
+}
+
+OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void)
+{
+ OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new();
+ mock_srv_ctx *ctx = mock_srv_ctx_new();
+
+ if (srv_ctx != NULL && ctx != NULL
+ && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
+ process_rr, process_genm, process_error,
+ process_certConf, process_pollReq))
+ return srv_ctx;
+
+ mock_srv_ctx_free(ctx);
+ OSSL_CMP_SRV_CTX_free(srv_ctx);
+ return NULL;
+}
+
+void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx != NULL)
+ mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx));
+ OSSL_CMP_SRV_CTX_free(srv_ctx);
+}
--- /dev/null
+/*
+ * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright Siemens AG 2018-2020
+ *
+ * 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
+ */
+
+#ifndef OSSL_APPS_CMP_MOCK_SRV_H
+# define OSSL_APPS_CMP_MOCK_SRV_H
+
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_CMP
+
+# include <openssl/cmp.h>
+
+OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void);
+void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
+
+int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
+int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *chain);
+int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *caPubs);
+int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
+ int fail_info, const char *text);
+int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count);
+int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec);
+
+# endif /* !defined(OPENSSL_NO_CMP) */
+#endif /* !defined(OSSL_APPS_CMP_MOCK_SRV_H) */
LIBS=../../libcrypto
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
- cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c
+ cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
+ cmp_server.c
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED),
"algorithm not supported"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTHASH_UNMATCHED), "certhash unmatched"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND),
"certificate not found"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTREQMSG_NOT_FOUND),
+ "certreqmsg not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND),
"certresponse not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH),
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS),
"error parsing pkistatus"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROCESSING_MSG),
+ "error processing msg"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE),
"error protecting message"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH),
"error setting certhash"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_TRANSFERRING_OUT),
+ "error transferring out"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_UNEXPECTED_CERTCONF),
+ "error unexpected certconf"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
"error validating protection"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
"missing sender identification"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE),
"missing trust store"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED),
+ "multiple requests not supported"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES),
"multiple san sources"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"},
}
/* push the given text string to the given PKIFREETEXT ft */
-int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text)
-{
- ASN1_UTF8STRING *utf8string;
-
- if (!ossl_assert(ft != NULL && text != NULL))
- return 0;
- if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
- return 0;
- if (!ASN1_STRING_set(utf8string, text, -1))
- goto err;
- if (!sk_ASN1_UTF8STRING_push(ft, utf8string))
- goto err;
- return 1;
-
- err:
- ASN1_UTF8STRING_free(utf8string);
- return 0;
-}
-
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
{
if (!ossl_assert(hdr != NULL && text != NULL))
&& (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL)
return 0;
- return ossl_cmp_pkifreetext_push_str(hdr->freeText, (char *)text->data);
+ return
+ ossl_cmp_sk_ASN1_UTF8STRING_push_str(hdr->freeText, (char *)text->data);
}
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
}
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
- STACK_OF(OSSL_CMP_ITAV) *itavs)
+ const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i;
OSSL_CMP_ITAV *itav;
}
/* return 1 if implicitConfirm in the generalInfo field of the header is set */
-int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
+int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
{
int itavCount;
int i;
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
/*
* The sender name is copied from the subject of the client cert, if any,
- * or else from the the subject name provided for certification requests.
+ * or else from the subject name provided for certification requests.
* As required by RFC 4210 section 5.1.1., if the sender name is not known
* to the client it set to NULL-DN. In this case for identification at least
* the senderKID must be set, which we take from any referenceValue given.
} infoValue;
} /* OSSL_CMP_ITAV */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ITAV)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV)
typedef struct ossl_cmp_certorenccert_st {
int type;
OSSL_CMP_PKIFREETEXT *statusString;
OSSL_CMP_PKIFAILUREINFO *failInfo;
} /* OSSL_CMP_PKISI */;
-DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
/*-
* crlEntryDetails Extensions OPTIONAL
* }
*/
-typedef struct ossl_cmp_revdetails_st {
+struct ossl_cmp_revdetails_st {
OSSL_CRMF_CERTTEMPLATE *certDetails;
X509_EXTENSIONS *crlEntryDetails;
-} OSSL_CMP_REVDETAILS;
+} /* OSSL_CMP_REVDETAILS */;
+typedef struct ossl_cmp_revdetails_st OSSL_CMP_REVDETAILS;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS)
DEFINE_STACK_OF(OSSL_CMP_REVDETAILS)
OSSL_CMP_PKISI *statusInfo;
} /* OSSL_CMP_CERTSTATUS */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS)
-
typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTCONFIRMCONTENT)
STACK_OF(X509) *extraCerts; /* 1 */
} /* OSSL_CMP_MSG */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_MSG)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG)
/*-
* ProtectedPart ::= SEQUENCE {
* }
*/
-/*
- * constants
- */
-/* certReqId for the first - and so far only - certificate request */
-# define OSSL_CMP_CERTREQID 0
-/* sequence id for the first - and so far only - revocation request */
-# define OSSL_CMP_REVREQSID 0
-/*
- * functions
- */
-
/* from cmp_asn.c */
int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
int no_self_issued, int no_dups, int prepend);
int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
int only_self_issued);
+STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store);
+int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
+ const char *text);
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
const ASN1_OCTET_STRING *src);
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
const ASN1_OCTET_STRING *nonce);
/* from cmp_status.c */
-OSSL_CMP_PKISI *
-ossl_cmp_statusinfo_new(int status, int fail_info, const char *text);
-int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *statusInfo);
+int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
const char *ossl_cmp_PKIStatus_to_string(int status);
-OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si);
+OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
-int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index);
+int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
/* from cmp_hdr.c */
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
const ASN1_OCTET_STRING *senderKID);
-int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text);
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
OSSL_CMP_ITAV *itav);
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
- STACK_OF(OSSL_CMP_ITAV) *itavs);
+ const STACK_OF(OSSL_CMP_ITAV) *itavs);
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
-int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
+int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
# define OSSL_CMP_SENDERNONCE_LENGTH 16
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
# define OSSL_CMP_PKIBODY_POLLREQ 25
# define OSSL_CMP_PKIBODY_POLLREP 26
# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP
+/* certReqId for the first - and so far only - certificate request */
+# define OSSL_CMP_CERTREQID 0
+/* sequence id for the first - and so far only - revocation request */
+# define OSSL_CMP_REVREQSID 0
const char *ossl_cmp_bodytype_to_string(int type);
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type);
int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg);
OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
OSSL_CRMF_CERTID *certId, int unprot_err);
OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx);
+OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
+ int64_t poll_after);
int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav);
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
- STACK_OF(OSSL_CMP_ITAV) *itavs);
+ const STACK_OF(OSSL_CMP_ITAV) *itavs);
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx);
-OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx);
+OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
+ const STACK_OF(OSSL_CMP_ITAV) *itavs);
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
int errorCode,
- OSSL_CMP_PKIFREETEXT *errorDetails,
- int unprotected);
-int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
- const X509 *cert);
+ const char *details, int unprotected);
+int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
+ ASN1_OCTET_STRING *hash);
OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
const char *text);
OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid);
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
int64_t poll_after);
OSSL_CMP_PKISI *
-ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
+ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep,
int rsid);
OSSL_CMP_POLLREP *
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
const OSSL_CMP_CERTRESPONSE *crep);
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
-/* BIO definitions */
-# define OSSL_d2i_CMP_MSG_bio(bp, p) \
- ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new, d2i_OSSL_CMP_MSG, bp, p)
-# define OSSL_i2d_CMP_MSG_bio(bp, o) \
- ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bp, o)
/* from cmp_protect.c */
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
-#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */
+#endif /* !defined(OSSL_CRYPTO_CMP_LOCAL_H) */
* Create CRMF certificate request message for IR/CR/KUR
* returns a pointer to the OSSL_CRMF_MSG on success, NULL on error
*/
-static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
- int rid, EVP_PKEY *rkey)
+static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid)
{
OSSL_CRMF_MSG *crm = NULL;
X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->clCert;
/* refcert defaults to current client cert */
+ EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
STACK_OF(GENERAL_NAME) *default_sans = NULL;
X509_NAME *subject = determine_subj(ctx, refcert, bodytype);
int crit = ctx->setSubjectAltNameCritical || subject == NULL;
/* RFC5280: subjectAltName MUST be critical if subject is null */
X509_EXTENSIONS *exts = NULL;
+ if (rkey == NULL)
+ rkey = ctx->pkey; /* default is independent of ctx->oldClCert */
if (rkey == NULL
|| (bodytype == OSSL_CMP_PKIBODY_KUR && refcert == NULL)) {
CMPerr(0, CMP_R_INVALID_ARGS);
OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
{
- EVP_PKEY *rkey;
- EVP_PKEY *privkey;
OSSL_CMP_MSG *msg;
OSSL_CRMF_MSG *crm = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
- rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
- if (rkey == NULL)
- return NULL;
- privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
-
if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR
&& type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) {
CMPerr(0, CMP_R_INVALID_ARGS);
/* body */
/* For P10CR the content has already been set in OSSL_CMP_MSG_create */
if (type != OSSL_CMP_PKIBODY_P10CR) {
+ EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
+
+ if (privkey == NULL)
+ privkey = ctx->pkey; /* default is independent of ctx->oldCert */
if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) {
CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
goto err;
}
- if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID, rkey)) == NULL
- || !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
- ctx->popoMethod)
- /* value.ir is same for cr and kur */
- || !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm))
+ if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID)) == NULL
+ || !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
+ ctx->popoMethod)
+ /* value.ir is same for cr and kur */
+ || !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm))
goto err;
crm = NULL;
/* TODO: here optional 2nd certreqmsg could be pushed to the stack */
|| !ASN1_INTEGER_set(resp->certReqId, certReqId))
goto err;
- status = ossl_cmp_pkisi_get_pkistatus(resp->status);
+ status = ossl_cmp_pkisi_get_status(resp->status);
if (status != OSSL_CMP_PKISTATUS_rejection
&& status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) {
if (encrypted) {
goto err;
if (!unprotectedErrors
- || ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
+ || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
}
if (!unprot_err
- || ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
+ || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
}
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
- STACK_OF(OSSL_CMP_ITAV) *itavs)
+ const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i;
OSSL_CMP_ITAV *itav = NULL;
* Creates a new General Message/Response with an empty itav stack
* returns a pointer to the PKIMessage on success, NULL on error
*/
-static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
+static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx,
+ const STACK_OF(OSSL_CMP_ITAV) *itavs,
+ int body_type, int err_code)
{
OSSL_CMP_MSG *msg = NULL;
return NULL;
if (ctx->genm_ITAVs != NULL
- && !ossl_cmp_msg_gen_push1_ITAVs(msg, ctx->genm_ITAVs))
+ && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
goto err;
if (!ossl_cmp_msg_protect(ctx, msg))
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
{
- return gen_new(ctx, OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
+ return gen_new(ctx, ctx->genm_ITAVs,
+ OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
}
-OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx)
+OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
+ const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
- return gen_new(ctx, OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
+ return gen_new(ctx, itavs,
+ OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
}
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
int errorCode,
- OSSL_CMP_PKIFREETEXT *errorDetails,
- int unprotected)
+ const char *details, int unprotected)
{
OSSL_CMP_MSG *msg = NULL;
+ OSSL_CMP_PKIFREETEXT *ft;
if (!ossl_assert(ctx != NULL && si != NULL))
return NULL;
if (!ASN1_INTEGER_set(msg->body->value.error->errorCode, errorCode))
goto err;
}
- if (errorDetails != NULL)
- if ((msg->body->value.error->errorDetails =
- sk_ASN1_UTF8STRING_deep_copy(errorDetails, ASN1_STRING_dup,
- ASN1_STRING_free)) == NULL)
+ if (details != NULL) {
+ if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
+ goto err;
+ msg->body->value.error->errorDetails = ft;
+ if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details))
goto err;
+ }
if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
goto err;
}
/*
- * OSSL_CMP_CERTSTATUS_set_certHash() calculates a hash of the certificate,
- * using the same hash algorithm as is used to create and verify the
- * certificate signature, and places the hash into the certHash field of a
- * OSSL_CMP_CERTSTATUS structure. This is used in the certConf message,
- * for example, to confirm that the certificate was received successfully.
+ * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
+ * This is used in the certConf message, for example,
+ * to confirm that the certificate was received successfully.
*/
-int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
- const X509 *cert)
+int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
+ ASN1_OCTET_STRING *hash)
{
- unsigned int len;
- unsigned char hash[EVP_MAX_MD_SIZE];
- int md_NID;
- const EVP_MD *md = NULL;
-
- if (!ossl_assert(certStatus != NULL && cert != NULL))
- return 0;
-
- /*-
- * select hash algorithm, as stated in Appendix F. Compilable ASN.1 defs:
- * the hash of the certificate, using the same hash algorithm
- * as is used to create and verify the certificate signature
- */
- if (OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_NID, NULL)
- && (md = EVP_get_digestbynid(md_NID)) != NULL) {
- if (!X509_digest(cert, md, hash, &len))
- goto err;
- if (!ossl_cmp_asn1_octet_string_set1_bytes(&certStatus->certHash, hash,
- len))
- goto err;
- } else {
- CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
+ if (!ossl_assert(certStatus != NULL))
return 0;
- }
-
+ ASN1_OCTET_STRING_free(certStatus->certHash);
+ certStatus->certHash = hash;
return 1;
- err:
- CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH);
- return 0;
}
/*
{
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_CERTSTATUS *certStatus = NULL;
+ ASN1_OCTET_STRING *certHash = NULL;
OSSL_CMP_PKISI *sinfo;
if (!ossl_assert(ctx != NULL && ctx->newCert != NULL))
* the hash of the certificate, using the same hash algorithm
* as is used to create and verify the certificate signature
*/
- if (!ossl_cmp_certstatus_set_certHash(certStatus, ctx->newCert))
+ if ((certHash = OSSL_CMP_X509_digest(ctx->newCert)) == NULL)
+ goto err;
+
+ if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash))
goto err;
+ certHash = NULL;
/*
* For any particular CertStatus, omission of the statusInfo field
* indicates ACCEPTANCE of the specified certificate. Alternatively,
* the CA/RA.
*/
sinfo = fail_info != 0 ?
- ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
- ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
+ OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
+ OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
if (sinfo == NULL)
goto err;
certStatus->statusInfo = sinfo;
err:
CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF);
OSSL_CMP_MSG_free(msg);
+ ASN1_OCTET_STRING_free(certHash);
return NULL;
}
* returns NULL on error
*/
OSSL_CMP_PKISI *
-ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
+ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
{
OSSL_CMP_PKISI *status;
BIO_free(bio);
return msg;
}
+
+OSSL_CMP_MSG *OSSL_d2i_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
+{
+ return ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new,
+ d2i_OSSL_CMP_MSG, bio, msg);
+}
+
+int OSSL_i2d_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
+{
+ return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
+}
--- /dev/null
+/*
+ * Copyright 2007-2019 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
+ */
+
+/* general CMP server functions */
+
+#include <openssl/asn1t.h>
+
+#include "cmp_local.h"
+
+/* explicit #includes not strictly needed since implied by the above: */
+#include <openssl/cmp.h>
+#include <openssl/err.h>
+
+/* the context for the generic CMP server */
+struct ossl_cmp_srv_ctx_st
+{
+ OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */
+ void *custom_ctx; /* pointer to specific server context */
+
+ OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
+ OSSL_CMP_SRV_rr_cb_t process_rr;
+ OSSL_CMP_SRV_genm_cb_t process_genm;
+ OSSL_CMP_SRV_error_cb_t process_error;
+ OSSL_CMP_SRV_certConf_cb_t process_certConf;
+ OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
+
+ int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
+ int acceptUnprotected; /* Accept requests with no/invalid prot. */
+ int acceptRAVerified; /* Accept ir/cr/kur with POPO RAVerified */
+ int grantImplicitConfirm; /* Grant implicit confirmation if requested */
+
+}; /* OSSL_CMP_SRV_CTX */
+
+void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx == NULL)
+ return;
+
+ OSSL_CMP_CTX_free(srv_ctx->ctx);
+ OPENSSL_free(srv_ctx);
+}
+
+OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void)
+{
+ OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));
+
+ if (ctx == NULL)
+ goto err;
+
+ if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL)
+ goto err;
+
+ /* all other elements are initialized to 0 or NULL, respectively */
+ return ctx;
+ err:
+ OSSL_CMP_SRV_CTX_free(ctx);
+ return NULL;
+}
+
+int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
+ OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
+ OSSL_CMP_SRV_rr_cb_t process_rr,
+ OSSL_CMP_SRV_genm_cb_t process_genm,
+ OSSL_CMP_SRV_error_cb_t process_error,
+ OSSL_CMP_SRV_certConf_cb_t process_certConf,
+ OSSL_CMP_SRV_pollReq_cb_t process_pollReq)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->custom_ctx = custom_ctx;
+ srv_ctx->process_cert_request = process_cert_request;
+ srv_ctx->process_rr = process_rr;
+ srv_ctx->process_genm = process_genm;
+ srv_ctx->process_error = process_error;
+ srv_ctx->process_certConf = process_certConf;
+ srv_ctx->process_pollReq = process_pollReq;
+ return 1;
+}
+
+OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+ return srv_ctx->ctx;
+}
+
+void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+ return srv_ctx->custom_ctx;
+}
+
+int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->sendUnprotectedErrors = val != 0;
+ return 1;
+}
+
+int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->acceptUnprotected = val != 0;
+ return 1;
+}
+
+int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->acceptRAVerified = val != 0;
+ return 1;
+}
+
+int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->grantImplicitConfirm = val != 0;
+ return 1;
+}
+
+/*
+ * Processes an ir/cr/p10cr/kur and returns a certification response.
+ * Only handles the first certification request contained in req
+ * returns an ip/cp/kup on success and NULL on error
+ */
+static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_MSG *msg = NULL;
+ OSSL_CMP_PKISI *si = NULL;
+ X509 *certOut = NULL;
+ STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
+ const OSSL_CRMF_MSG *crm = NULL;
+ const X509_REQ *p10cr = NULL;
+ int bodytype;
+ int certReqId;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+
+ switch (ossl_cmp_msg_get_bodytype(req)) {
+ case OSSL_CMP_PKIBODY_P10CR:
+ case OSSL_CMP_PKIBODY_CR:
+ bodytype = OSSL_CMP_PKIBODY_CP;
+ break;
+ case OSSL_CMP_PKIBODY_IR:
+ bodytype = OSSL_CMP_PKIBODY_IP;
+ break;
+ case OSSL_CMP_PKIBODY_KUR:
+ bodytype = OSSL_CMP_PKIBODY_KUP;
+ break;
+ default:
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ return NULL;
+ }
+
+ if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) {
+ certReqId = OSSL_CMP_CERTREQID;
+ p10cr = req->body->value.p10cr;
+ } else {
+ OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */
+
+ if (sk_OSSL_CRMF_MSG_num(reqs) != 1) { /* TODO: handle case > 1 */
+ CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
+ return NULL;
+ }
+
+ if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
+ CMPerr(0, CMP_R_CERTREQMSG_NOT_FOUND);
+ return NULL;
+ }
+ certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
+ }
+
+ if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
+ /* Proof of possession could not be verified */
+ si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
+ 1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
+ ERR_reason_error_string(ERR_peek_error()));
+ if (si == NULL)
+ return NULL;
+ } else {
+ OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req);
+
+ si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr,
+ &certOut, &chainOut, &caPubs);
+ if (si == NULL)
+ goto err;
+ /* set OSSL_CMP_OPT_IMPLICITCONFIRM if and only if transaction ends */
+ if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, OSSL_CMP_OPT_IMPLICITCONFIRM,
+ ossl_cmp_hdr_has_implicitConfirm(hdr)
+ && srv_ctx->grantImplicitConfirm
+ /* do not set if polling starts: */
+ && certOut != NULL))
+ goto err;
+ }
+
+ msg = ossl_cmp_certRep_new(srv_ctx->ctx, bodytype, certReqId, si,
+ certOut, chainOut, caPubs, 0 /* encrypted */,
+ srv_ctx->sendUnprotectedErrors);
+ /*
+ * TODO when implemented in ossl_cmp_certrep_new():
+ * in case OSSL_CRMF_POPO_KEYENC, set encrypted
+ */
+ if (msg == NULL)
+ CMPerr(0, CMP_R_ERROR_CREATING_CERTREP);
+
+ err:
+ OSSL_CMP_PKISI_free(si);
+ X509_free(certOut);
+ sk_X509_pop_free(chainOut, X509_free);
+ sk_X509_pop_free(caPubs, X509_free);
+ return msg;
+}
+
+static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_MSG *msg = NULL;
+ OSSL_CMP_REVDETAILS *details;
+ OSSL_CRMF_CERTID *certId;
+ OSSL_CRMF_CERTTEMPLATE *tmpl;
+ X509_NAME *issuer;
+ ASN1_INTEGER *serial;
+ OSSL_CMP_PKISI *si;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+
+ if (sk_OSSL_CMP_REVDETAILS_num(req->body->value.rr) != 1) {
+ /* TODO: handle multiple elements if multiple requests have been sent */
+ CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
+ return NULL;
+ }
+
+ if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr,
+ OSSL_CMP_REVREQSID)) == NULL) {
+ CMPerr(0, CMP_R_ERROR_PROCESSING_MSG);
+ return NULL;
+ }
+
+ tmpl = details->certDetails;
+ issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
+ serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
+ /* here issuer and serial may safely be NULL */
+ if ((certId = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL)
+ return NULL;
+ if ((si = srv_ctx->process_rr(srv_ctx, req, issuer, serial)) == NULL)
+ goto err;
+
+ if ((msg = ossl_cmp_rp_new(srv_ctx->ctx, si, certId,
+ srv_ctx->sendUnprotectedErrors)) == NULL)
+ CMPerr(0, CMP_R_ERROR_CREATING_RR);
+
+ err:
+ OSSL_CRMF_CERTID_free(certId);
+ OSSL_CMP_PKISI_free(si);
+ return msg;
+}
+
+/*
+ * Processes genm and creates a genp message mirroring the contents of the
+ * incoming message
+ */
+static OSSL_CMP_MSG *process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_GENMSGCONTENT *itavs;
+ OSSL_CMP_MSG *msg;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+
+ if (!srv_ctx->process_genm(srv_ctx, req, req->body->value.genm, &itavs))
+ return NULL;
+
+ msg = ossl_cmp_genp_new(srv_ctx->ctx, itavs);
+ sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
+ return msg;
+}
+
+static OSSL_CMP_MSG *process_error(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_ERRORMSGCONTENT *errorContent;
+ OSSL_CMP_MSG *msg;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+ errorContent = req->body->value.error;
+ srv_ctx->process_error(srv_ctx, req, errorContent->pKIStatusInfo,
+ errorContent->errorCode, errorContent->errorDetails);
+
+ if ((msg = ossl_cmp_pkiconf_new(srv_ctx->ctx)) == NULL)
+ CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
+ return msg;
+}
+
+static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_CTX *ctx;
+ OSSL_CMP_CERTCONFIRMCONTENT *ccc;
+ int num;
+ OSSL_CMP_MSG *msg = NULL;
+ OSSL_CMP_CERTSTATUS *status = NULL;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+
+ ctx = srv_ctx->ctx;
+ ccc = req->body->value.certConf;
+ num = sk_OSSL_CMP_CERTSTATUS_num(ccc);
+
+ if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICITCONFIRM) == 1) {
+ CMPerr(0, CMP_R_ERROR_UNEXPECTED_CERTCONF);
+ return NULL;
+ }
+
+ if (num == 0) {
+ ossl_cmp_err(ctx, "certificate rejected by client");
+ } else {
+ if (num > 1)
+ ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
+ status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID);
+ }
+
+ if (status != NULL) {
+ int certReqId = ossl_cmp_asn1_get_int(status->certReqId);
+ ASN1_OCTET_STRING *certHash = status->certHash;
+ OSSL_CMP_PKISI *si = status->statusInfo;
+
+ if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si))
+ return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */
+
+ if (si != NULL && ossl_cmp_pkisi_get_status(si)
+ != OSSL_CMP_PKISTATUS_accepted) {
+ int pki_status = ossl_cmp_pkisi_get_status(si);
+ const char *str = ossl_cmp_PKIStatus_to_string(pki_status);
+
+ ossl_cmp_log2(INFO, ctx, "certificate rejected by client %s %s",
+ str == NULL ? "without" : "with",
+ str == NULL ? "PKIStatus" : str);
+ }
+ }
+
+ if ((msg = ossl_cmp_pkiconf_new(ctx)) == NULL)
+ CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
+ return msg;
+}
+
+static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_POLLREQCONTENT *prc;
+ OSSL_CMP_POLLREQ *pr;
+ int certReqId;
+ OSSL_CMP_MSG *certReq;
+ int64_t check_after = 0;
+ OSSL_CMP_MSG *msg = NULL;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+
+ prc = req->body->value.pollReq;
+ if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) { /* TODO: handle case > 1 */
+ CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
+ return NULL;
+ }
+
+ pr = sk_OSSL_CMP_POLLREQ_value(prc, 0);
+ certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
+ if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
+ &certReq, &check_after))
+ return NULL;
+
+ if (certReq != NULL) {
+ msg = process_cert_request(srv_ctx, certReq);
+ OSSL_CMP_MSG_free(certReq);
+ } else {
+ if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
+ check_after)) == NULL)
+ CMPerr(0, CMP_R_ERROR_CREATING_POLLREP);
+ }
+ return msg;
+}
+
+/*
+ * Determines whether missing protection is allowed
+ */
+static int unprotected_exception(const OSSL_CMP_CTX *ctx,
+ const OSSL_CMP_MSG *req,
+ int invalid_protection,
+ int accept_unprotected_requests)
+{
+ if (accept_unprotected_requests) {
+ ossl_cmp_log1(WARN, ctx, "ignoring %s protection of request message",
+ invalid_protection ? "invalid" : "missing");
+ return 1;
+ }
+ if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_ERROR
+ && OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS) == 1) {
+ ossl_cmp_warn(ctx, "ignoring missing protection of error message");
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * returns created message and NULL on internal error
+ */
+OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_CTX *ctx;
+ OSSL_CMP_PKIHEADER *hdr;
+ int req_type, rsp_type;
+ OSSL_CMP_MSG *rsp = NULL;
+
+ if (srv_ctx == NULL || srv_ctx->ctx == NULL
+ || req == NULL || req->body == NULL
+ || (hdr = OSSL_CMP_MSG_get0_header(req)) == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ ctx = srv_ctx->ctx;
+
+ if (hdr->sender->type != GEN_DIRNAME) {
+ CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
+ goto err;
+ }
+ if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
+ goto err;
+
+ req_type = ossl_cmp_msg_get_bodytype(req);
+ switch (req_type) {
+ case OSSL_CMP_PKIBODY_IR:
+ case OSSL_CMP_PKIBODY_CR:
+ case OSSL_CMP_PKIBODY_P10CR:
+ case OSSL_CMP_PKIBODY_KUR:
+ case OSSL_CMP_PKIBODY_RR:
+ case OSSL_CMP_PKIBODY_GENM:
+ case OSSL_CMP_PKIBODY_ERROR:
+ if (ctx->transactionID != NULL) {
+ char *tid;
+
+ tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
+ ctx->transactionID->length);
+ ossl_cmp_log1(WARN, ctx,
+ "Assuming that last transaction with ID=%s got aborted",
+ tid);
+ OPENSSL_free(tid);
+ }
+ /* start of a new transaction, set transactionID and senderNonce */
+ if (!OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID)
+ || !ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
+ goto err;
+ break;
+ default:
+ /* transactionID should be already initialized */
+ if (ctx->transactionID == NULL) {
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ /* ignore any (extra) error in next two function calls: */
+ (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
+ (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
+ goto err;
+ }
+ }
+
+ if (ossl_cmp_msg_check_received(ctx, req, unprotected_exception,
+ srv_ctx->acceptUnprotected) < 0)
+ goto err;
+
+ switch (req_type) {
+ case OSSL_CMP_PKIBODY_IR:
+ case OSSL_CMP_PKIBODY_CR:
+ case OSSL_CMP_PKIBODY_P10CR:
+ case OSSL_CMP_PKIBODY_KUR:
+ if (srv_ctx->process_cert_request == NULL)
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ else
+ rsp = process_cert_request(srv_ctx, req);
+ break;
+ case OSSL_CMP_PKIBODY_RR:
+ if (srv_ctx->process_rr == NULL)
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ else
+ rsp = process_rr(srv_ctx, req);
+ break;
+ case OSSL_CMP_PKIBODY_GENM:
+ if (srv_ctx->process_genm == NULL)
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ else
+ rsp = process_genm(srv_ctx, req);
+ break;
+ case OSSL_CMP_PKIBODY_ERROR:
+ if (srv_ctx->process_error == NULL)
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ else
+ rsp = process_error(srv_ctx, req);
+ break;
+ case OSSL_CMP_PKIBODY_CERTCONF:
+ if (srv_ctx->process_certConf == NULL)
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ else
+ rsp = process_certConf(srv_ctx, req);
+ break;
+ case OSSL_CMP_PKIBODY_POLLREQ:
+ if (srv_ctx->process_pollReq == NULL)
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ else
+ rsp = process_pollReq(srv_ctx, req);
+ break;
+ default:
+ /* TODO possibly support further request message types */
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ }
+
+ err:
+ if (rsp == NULL) {
+ /* on error, try to respond with CMP error message to client */
+ const char *data = NULL;
+ int flags = 0;
+ unsigned long err = ERR_peek_error_data(&data, &flags);
+ int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest;
+ /* TODO fail_info could be more specific */
+ OSSL_CMP_PKISI *si = NULL;
+
+ if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
+ fail_info, NULL)) == NULL)
+ return 0;
+ if (err != 0 && (flags & ERR_TXT_STRING) != 0)
+ data = ERR_reason_error_string(err);
+ rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
+ err != 0 ? ERR_GET_REASON(err) : -1,
+ data, srv_ctx->sendUnprotectedErrors);
+ OSSL_CMP_PKISI_free(si);
+ }
+
+ /* possibly close the transaction */
+ rsp_type =
+ rsp != NULL ? ossl_cmp_msg_get_bodytype(rsp) : OSSL_CMP_PKIBODY_ERROR;
+ switch (rsp_type) {
+ case OSSL_CMP_PKIBODY_IP:
+ case OSSL_CMP_PKIBODY_CP:
+ case OSSL_CMP_PKIBODY_KUP:
+ case OSSL_CMP_PKIBODY_RP:
+ if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICITCONFIRM) == 0)
+ break;
+ /* fall through */
+
+ case OSSL_CMP_PKIBODY_PKICONF:
+ case OSSL_CMP_PKIBODY_GENP:
+ case OSSL_CMP_PKIBODY_ERROR:
+ /* TODO possibly support further terminating response message types */
+ (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); /* ignore any error */
+
+ default: /* not closing transaction in other cases */
+ break;
+ }
+ return rsp;
+}
+
+/*
+ * Server interface that may substitute OSSL_CMP_MSG_http_perform at the client.
+ * The OSSL_CMP_SRV_CTX must be set as client_ctx->transfer_cb_arg.
+ * returns received message on success, else NULL and pushes an element on the
+ * error stack.
+ */
+OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_SRV_CTX *srv_ctx = NULL;
+
+ if (client_ctx == NULL || req == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+
+ if ((srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(client_ctx)) == NULL) {
+ CMPerr(0, CMP_R_ERROR_TRANSFERRING_OUT);
+ return 0;
+ }
+
+ return OSSL_CMP_SRV_process_request(srv_ctx, req);
+}
/* CMP functions related to PKIStatus */
-int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *si)
+int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si)
{
if (!ossl_assert(si != NULL && si->status != NULL))
return -1;
return ossl_cmp_asn1_get_int(si->status);
}
-/*
- * return the declared identifier and a short explanation for the PKIStatus
- * value as specified in RFC4210, Appendix F.
- */
const char *ossl_cmp_PKIStatus_to_string(int status)
{
switch (status) {
}
}
-/*
- * returns a pointer to the statusString contained in a PKIStatusInfo
- * returns NULL on error
- */
-OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si)
+OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si)
{
if (!ossl_assert(si != NULL))
return NULL;
return si->statusString;
}
-/*
- * returns the FailureInfo bits of the given PKIStatusInfo
- * returns -1 on error
- */
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si)
{
int i;
return res;
}
-/*
- * internal function
+/*-
* convert PKIFailureInfo number to human-readable string
- *
- * returns pointer to static string
- * returns NULL on error
+ * returns pointer to static string, or NULL on error
*/
static const char *CMP_PKIFAILUREINFO_to_string(int number)
{
}
}
-/*
- * checks PKIFailureInfo bits in a given PKIStatusInfo
- * returns 1 if a given bit is set, 0 if not, -1 on error
- */
-int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index)
+int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int bit_index)
{
if (!ossl_assert(si != NULL && si->failInfo != NULL))
return -1;
return ASN1_BIT_STRING_get_bit(si->failInfo, bit_index);
}
-/*
+/*-
* place human-readable error string created from PKIStatusInfo in given buffer
* returns pointer to the same buffer containing the string, or NULL on error
*/
-char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
- size_t bufsize)
+static
+char *snprint_PKIStatusInfo_parts(int status, int fail_info,
+ const OSSL_CMP_PKIFREETEXT *status_strings,
+ char *buf, size_t bufsize)
{
- int status, failure, fail_info;
+ int failure;
const char *status_string, *failure_string;
- OSSL_CMP_PKIFREETEXT *status_strings;
ASN1_UTF8STRING *text;
int i;
int printed_chars;
int n_status_strings;
char *write_ptr = buf;
-#define ADVANCE_BUFFER \
- if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \
- return NULL; \
- write_ptr += printed_chars; \
- bufsize -= printed_chars;
-
- if (ctx == NULL
- || buf == NULL
- || (status = OSSL_CMP_CTX_get_status(ctx)) < 0
+ if (buf == NULL
+ || status < 0
|| (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL)
return NULL;
+
+#define ADVANCE_BUFFER \
+ if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \
+ return NULL; \
+ write_ptr += printed_chars; \
+ bufsize -= printed_chars;
+
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string);
ADVANCE_BUFFER;
/* failInfo is optional and may be empty */
- if ((fail_info = OSSL_CMP_CTX_get_failInfoCode(ctx)) > 0) {
+ if (fail_info != 0) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: ");
ADVANCE_BUFFER;
for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) {
failure_string = CMP_PKIFAILUREINFO_to_string(failure);
if (failure_string != NULL) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s",
- failure > 0 ? ", " : "",
+ failinfo_found ? ", " : "",
failure_string);
ADVANCE_BUFFER;
failinfo_found = 1;
}
/* statusString sequence is optional and may be empty */
- status_strings = OSSL_CMP_CTX_get0_statusString(ctx);
n_status_strings = sk_ASN1_UTF8STRING_num(status_strings);
if (n_status_strings > 0) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ",
return buf;
}
-/*
+char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo,
+ char *buf, size_t bufsize)
+{
+ int failure_info;
+
+ if (statusInfo == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+
+ failure_info = ossl_cmp_pkisi_get_pkifailureinfo(statusInfo);
+
+ return snprint_PKIStatusInfo_parts(ASN1_INTEGER_get(statusInfo->status),
+ failure_info,
+ statusInfo->statusString, buf, bufsize);
+}
+
+char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf,
+ size_t bufsize)
+{
+ if (ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+
+ return snprint_PKIStatusInfo_parts(OSSL_CMP_CTX_get_status(ctx),
+ OSSL_CMP_CTX_get_failInfoCode(ctx),
+ OSSL_CMP_CTX_get0_statusString(ctx),
+ buf, bufsize);
+}
+
+/*-
* Creates a new PKIStatusInfo structure and fills it in
* returns a pointer to the structure on success, NULL on error
* note: strongly overlaps with TS_RESP_CTX_set_status_info()
* and TS_RESP_CTX_add_failure_info() in ../ts/ts_rsp_sign.c
*/
-OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
+OSSL_CMP_PKISI *OSSL_CMP_STATUSINFO_new(int status, int fail_info,
const char *text)
{
OSSL_CMP_PKISI *si = OSSL_CMP_PKISI_new();
return result;
}
+int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
+ const char *text)
+{
+ ASN1_UTF8STRING *utf8string;
+
+ if (!ossl_assert(sk != NULL && text != NULL))
+ return 0;
+ if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
+ return 0;
+ if (!ASN1_STRING_set(utf8string, text, -1))
+ goto err;
+ if (!sk_ASN1_UTF8STRING_push(sk, utf8string))
+ goto err;
+ return 1;
+
+ err:
+ ASN1_UTF8STRING_free(utf8string);
+ return 0;
+}
+
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
const ASN1_OCTET_STRING *src)
{
*tgt = new;
return 1;
}
+
+/*
+ * calculate a digest of the given certificate,
+ * using the same hash algorithm as in the certificate signature.
+ */
+ASN1_OCTET_STRING *OSSL_CMP_X509_digest(const X509 *cert)
+{
+ unsigned int len;
+ unsigned char hash[EVP_MAX_MD_SIZE];
+ int md_NID;
+ const EVP_MD *md = NULL;
+ ASN1_OCTET_STRING *new = NULL;
+
+ if (!ossl_assert(cert != NULL))
+ return NULL;
+
+ /*-
+ * select hash algorithm, as stated in CMP RFC 4210 Appendix F.
+ * Compilable ASN.1 defs:
+ * the hash of the certificate, using the same hash algorithm
+ * as is used to create and verify the certificate signature
+ */
+ if (!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_NID, NULL)
+ || (md = EVP_get_digestbynid(md_NID)) == NULL) {
+ CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
+ return NULL;
+ }
+ if (!X509_digest(cert, md, hash, &len)
+ || (new = ASN1_OCTET_STRING_new()) == NULL)
+ return NULL;
+ if (!(ASN1_OCTET_STRING_set(new, hash, len))) {
+ ASN1_OCTET_STRING_free(new);
+ return NULL;
+ }
+ return new;
+}
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
"iterationcount below 100"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
+ {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
+ "popo inconsistent public key"},
+ {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY),
+ "popo missing public key"},
+ {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT),
+ "popo missing subject"},
+ {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED),
+ "popo raverified not accepted"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE),
"setting mac algor failure"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE),
"unsupported method for creating popo"},
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD),
"unsupported popo method"},
- {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED),
- "unsupported popo not accepted"},
{0, NULL}
};
return (int)res;
}
-int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm)
+int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm)
{
if (crm == NULL || /* not really needed: */ crm->certReq == NULL) {
CRMFerr(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, CRMF_R_NULL_ARGUMENT);
switch (req->popo->type) {
case OSSL_CRMF_POPO_RAVERIFIED:
- if (acceptRAVerified)
- return 1;
+ if (!acceptRAVerified) {
+ CRMFerr(0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED);
+ return 0;
+ }
break;
case OSSL_CRMF_POPO_SIGNATURE:
pubkey = req->certReq->certTemplate->publicKey;
+ if (pubkey == NULL) {
+ CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
+ return 0;
+ }
sig = req->popo->value.signature;
if (sig->poposkInput != NULL) {
/*
* the public key from the certificate template. This MUST be
* exactly the same value as contained in the certificate template.
*/
- const ASN1_ITEM *rptr = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT);
-
- if (pubkey == NULL
- || sig->poposkInput->publicKey == NULL
- || X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey)
- || ASN1_item_verify(rptr, sig->algorithmIdentifier,
- sig->signature, sig->poposkInput,
- X509_PUBKEY_get0(pubkey)) < 1)
- break;
+ if (sig->poposkInput->publicKey == NULL) {
+ CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
+ return 0;
+ }
+ if (X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey) != 0) {
+ CRMFerr(0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY);
+ return 0;
+ }
+ /*
+ * TODO check the contents of the authInfo sub-field,
+ * see RFC 4211 https://tools.ietf.org/html/rfc4211#section-4.1
+ */
+ if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT),
+ sig->algorithmIdentifier, sig->signature,
+ sig->poposkInput,
+ X509_PUBKEY_get0(pubkey)) < 1)
+ return 0;
} else {
- if (pubkey == NULL
- || req->certReq->certTemplate->subject == NULL
- || ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
- sig->algorithmIdentifier,
- sig->signature,
- req->certReq,
- X509_PUBKEY_get0(pubkey)) < 1)
- break;
+ if (req->certReq->certTemplate->subject == NULL) {
+ CRMFerr(0, CRMF_R_POPO_MISSING_SUBJECT);
+ return 0;
+ }
+ if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
+ sig->algorithmIdentifier, sig->signature,
+ req->certReq, X509_PUBKEY_get0(pubkey)) < 1)
+ return 0;
}
- return 1;
+ break;
case OSSL_CRMF_POPO_KEYENC:
/*
* TODO: when OSSL_CMP_certrep_new() supports encrypted certs,
CRMF_R_UNSUPPORTED_POPO_METHOD);
return 0;
}
- CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
- CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED);
- return 0;
+ return 1;
}
/* retrieves the serialNumber of the given cert template or NULL on error */
-ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(OSSL_CRMF_CERTTEMPLATE *tmpl)
+ASN1_INTEGER
+*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl)
{
return tmpl != NULL ? tmpl->serialNumber : NULL;
}
/* retrieves the issuer name of the given cert template or NULL on error */
-X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl)
+X509_NAME
+*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl)
{
return tmpl != NULL ? tmpl->issuer : NULL;
}
* returns a pointer to the decrypted certificate
* returns NULL on error or if no certificate available
*/
-X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
+X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
EVP_PKEY *pkey)
{
X509 *cert = NULL; /* decrypted certificate */
BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables
CMP_R_ALGORITHM_NOT_SUPPORTED:139:algorithm not supported
CMP_R_BAD_REQUEST_ID:108:bad request id
+CMP_R_CERTHASH_UNMATCHED:156:certhash unmatched
CMP_R_CERTID_NOT_FOUND:109:certid not found
CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found
+CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found
CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found
CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match
CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection
CMP_R_ERROR_CREATING_RP:125:error creating rp
CMP_R_ERROR_CREATING_RR:126:error creating rr
CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus
+CMP_R_ERROR_PROCESSING_MSG:158:error processing msg
CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
+CMP_R_ERROR_TRANSFERRING_OUT:159:error transferring out
+CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
CMP_R_MISSING_PROTECTION:143:missing protection
CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification
CMP_R_MISSING_TRUST_STORE:144:missing trust store
+CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED:161:multiple requests not supported
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
CMP_R_NO_STDIO:194:no stdio
CMP_R_NO_SUITABLE_SENDER_CERT:145:no suitable sender cert
CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100
CRMF_R_MALFORMED_IV:101:malformed iv
CRMF_R_NULL_ARGUMENT:109:null argument
+CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key
+CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key
+CRMF_R_POPO_MISSING_SUBJECT:119:popo missing subject
+CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted
CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure
CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure
CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm
CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\
unsupported method for creating popo
CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method
-CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted
CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name
CRYPTO_R_CONFLICTING_NAMES:118:conflicting names
CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
ossl_cmp_hdr_generalinfo_item_push0,
ossl_cmp_hdr_generalinfo_items_push1,
ossl_cmp_hdr_set_implicitConfirm,
-ossl_cmp_hdr_check_implicitConfirm,
+ossl_cmp_hdr_has_implicitConfirm,
ossl_cmp_hdr_init
- functions manipulating CMP message headers
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr,
ASN1_UTF8STRING *text);
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
- int ossl_cmp_hdr_check_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_hdr_has_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
=head1 DESCRIPTION
ossl_cmp_hdr_set_implicitConfirm() sets implicitConfirm in the generalInfo field
of the PKIMessage header.
-ossl_cmp_hdr_check_implicitConfirm() returns 1 if implicitConfirm is
+ossl_cmp_hdr_has_implicitConfirm() returns 1 if implicitConfirm is
set int generalInfo field of the given PKIMessage header, 0 if not.
ossl_cmp_hdr_init() initializes a PKIHeader structure based on the
--- /dev/null
+=pod
+
+=head1 NAME
+
+ossl_cmp_mock_srv_new,
+ossl_cmp_mock_srv_free,
+ossl_cmp_mock_srv_set1_certOut,
+ossl_cmp_mock_srv_set1_chainOut,
+ossl_cmp_mock_srv_set1_caPubsOut,
+ossl_cmp_mock_srv_set_statusInfo,
+ossl_cmp_mock_srv_set_send_error,
+ossl_cmp_mock_srv_set_pollCount,
+ossl_cmp_mock_srv_set_checkAfterTime
+- functions used for testing with CMP mock server
+
+=head1 SYNOPSIS
+
+ #include <openssl/cmp.h>
+
+ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void);
+ void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
+
+ int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
+ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *chain);
+ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *caPubs);
+ int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
+ int fail_info, const char *text);
+ int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+ int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count);
+ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec);
+
+=head1 DESCRIPTION
+
+ossl_cmp_mock_srv_new() allocates the contexts for the CMP mock server.
+
+ossl_cmp_mock_srv_free() deallocates the contexts for the CMP mock server.
+
+OSSL_CMP_SRV_CTX_set1_certOut() sets the certificate to be returned in
+cp/ip/kup.
+
+OSSL_CMP_SRV_CTX_set1_chainOut() sets the certificate chain to be added to
+the extraCerts in a cp/ip/kup.
+It should to useful to validate B<certOut>.
+
+OSSL_CMP_SRV_CTX_set1_caPubsOut() sets the caPubs to be returned in an ip.
+
+OSSL_CMP_SRV_CTX_set_statusInfo() sets the status info to be returned.
+
+OSSL_CMP_SRV_CTX_set_send_error() enables enforcement of error responses.
+
+OSSL_CMP_SRV_CTX_set_pollCount() sets the number of polls before cert response.
+
+OSSL_CMP_SRV_CTX_set_checkAfterTime() sets the number of seconds
+the client should wait for the next poll.
+
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+ossl_cmp_mock_srv() returns a B<OSSL_CMP_SRV_CTX> structure on success,
+NULL on error.
+
+ossl_cmp_mock_srv_free() does not return a value.
+
+All other functions return 1 on success, 0 on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+ossl_cmp_pkisi_get_status,
+ossl_cmp_PKIStatus_to_string,
+ossl_cmp_pkisi_get0_statusString,
+ossl_cmp_pkisi_get_pkifailureinfo,
+ossl_cmp_pkisi_check_pkifailureinfo
+- functions for managing PKI status information
+
+=head1 SYNOPSIS
+
+ #include "cmp.h"
+
+# define OSSL_CMP_PKIFAILUREINFO_badAlg 0
+# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1
+# define OSSL_CMP_PKIFAILUREINFO_badRequest 2
+# define OSSL_CMP_PKIFAILUREINFO_badTime 3
+# define OSSL_CMP_PKIFAILUREINFO_badCertId 4
+# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5
+# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6
+# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7
+# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8
+# define OSSL_CMP_PKIFAILUREINFO_badPOP 9
+# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10
+# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11
+# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12
+# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13
+# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14
+# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15
+# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16
+# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17
+# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18
+# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19
+# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20
+# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21
+# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22
+# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23
+# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24
+# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25
+# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26
+# define OSSL_CMP_PKIFAILUREINFO_MAX 26
+
+ int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
+ const char *ossl_cmp_PKIStatus_to_string(int status);
+ OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
+ int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
+ int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
+
+=head1 DESCRIPTION
+
+ossl_cmp_pkisi_get_status() returns the PKIStatus of B<si>, or -1 on error.
+
+ossl_cmp_PKIStatus_to_string() returns a human-readable string representing
+the PKIStatus values as specified in RFC 4210, Appendix F.
+
+ossl_cmp_pkisi_get0_statusString() returns a direct pointer to the statusString
+field contained in B<si>.
+
+ossl_cmp_pkisi_get_pkifailureinfo() returns the PKIFailureInfo bits
+of B<si>, encoded as integer, or -1 on error.
+
+ossl_cmp_pkisi_check_pkifailureinfo() returns the state of the bit (0 or 1)
+with index B<index> in the PKIFailureInfo of the B<si>, or -1 on error.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+See the individual functions above.
+
+=head1 SEE ALSO
+
+L<OSSL_CMP_CTX_new(3)>, L<ossl_cmp_certReq_new(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
+++ /dev/null
-=pod
-
-=head1 NAME
-
-ossl_cmp_statusinfo_new,
-ossl_cmp_pkisi_pkistatus_get,
-ossl_cmp_pkisi_pkifailureinfo_get,
-ossl_cmp_pkisi_pkifailureinfo_check,
-ossl_cmp_pkisi_failinfo_get0,
-ossl_cmp_pkisi_statusstring_get0,
-ossl_pkisi_snprint
-- functions for managing PKI status information
-
-=head1 SYNOPSIS
-
- #include "cmp.h"
-
-# define OSSL_CMP_PKIFAILUREINFO_badAlg 0
-# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1
-# define OSSL_CMP_PKIFAILUREINFO_badRequest 2
-# define OSSL_CMP_PKIFAILUREINFO_badTime 3
-# define OSSL_CMP_PKIFAILUREINFO_badCertId 4
-# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5
-# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6
-# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7
-# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8
-# define OSSL_CMP_PKIFAILUREINFO_badPOP 9
-# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10
-# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11
-# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12
-# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13
-# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14
-# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15
-# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16
-# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17
-# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18
-# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19
-# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20
-# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21
-# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22
-# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23
-# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24
-# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25
-# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26
-# define OSSL_CMP_PKIFAILUREINFO_MAX 26
-
- OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
- const char *text);
- int ossl_cmp_pkisi_pkistatus_get(OSSL_CMP_PKISI *si);
- int ossl_cmp_pkisi_pkifailureinfo_get(OSSL_CMP_PKISI *si);
- int ossl_cmp_pkisi_pkifailureinfo_check(OSSL_CMP_PKISI *si, int bit_index);
- OSSL_CMP_PKIFAILUREINFO *ossl_cmp_pkisi_failinfo_get0(const OSSL_CMP_PKISI *si);
- OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_statusstring_get0(const OSSL_CMP_PKISI *si);
- char *ossl_pkisi_snprint(OSSL_CMP_PKISI *si, char *buf, int bufsize);
-
-=head1 DESCRIPTION
-
-ossl_cmp_statusinfo_new() creates a new PKIStatusInfo structure and fills it
-with the given values. It sets the status field to B<status>.
-If B<text> is not NULL, it is copied to statusString.
-B<fail_info> is is interpreted as bit pattern for the failInfo field.
-Returns a pointer to the structure on success, or NULL on error.
-
-ossl_cmp_pkisi_pkistatus_get() returns the PKIStatus of B<si>, or -1 on error.
-
-ossl_cmp_pkisi_pkifailureinfo_get() returns the PKIFailureInfo bits
-of B<si>, encoded as integer, or -1 on error.
-
-ossl_cmp_pkisi_pkifailureinfo_check() returns the state of the bit (0 or 1)
-with index B<bit_index> in the PKIFailureInfo of the B<si>, or -1 on error.
-
-ossl_cmp_pkisi_failinfo_get0() returns a direct pointer to the failInfo
-field contained in B<si>, or NULL on error.
-
-ossl_cmp_pkisi_statusstring_get0() returns a direct pointer to the statusString
-field contained in B<si>.
-
-ossl_pkisi_snprint() places at max B<bufsize> characters of human-readable
-error string of B<si> in pre-allocated B<buf>. Returns pointer to the same
-B<buf> containing the string, or NULL on error.
-
-=head1 NOTES
-
-CMP is defined in RFC 4210 (and CRMF in RFC 4211).
-
-=head1 RETURN VALUES
-
-See the individual functions above.
-
-=head1 SEE ALSO
-
-L<OSSL_CMP_CTX_new(3)>, L<ossl_cmp_certReq_new(3)>
-
-=head1 HISTORY
-
-The OpenSSL CMP support was added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
OSSL_CMP_OPT_MAC_ALGNID
The MAC algorithm NID to be used in RFC 4210's MSG_MAC_ALG,
- if applicable used for message protection.
+ if applicable used for message protection.
Default is HMAC-SHA1 as per RFC 4210.
=item B<OSSL_CMP_OPT_REVOCATION_REASON>
OSSL_CMP_CTX_get0_untrusted_certs(OSSL_CMP_CTX *ctx) returns a pointer to the
list of untrusted certs, which my be empty if unset.
-OSSL_CMP_CTX_set1_clCert() sets the client certificate in the given
-OSSL_CMP_CTX structure. The client certificate will then be used by the
-functions to set the "sender" field for outgoing messages and it will be
-included in the extraCerts field.
-
-OSSL_CMP_CTX_set1_pkey() sets the private key corresponding to the client
-certificate set with B<OSSL_CMP_CTX_set1_clCert()> in the given CMP context.
-Used to create the protection in case of MSG_SIG_ALG.
-
-OSSL_CMP_CTX_set1_referenceValue() sets the given referenceValue in the given
-B<ctx> or clears it if the B<ref> argument is NULL.
-
-OSSL_CMP_CTX_set1_secretValue() sets the B<sec> with the length B<len> in the
-given B<ctx> or clears it if the B<sec> argument is NULL.
+OSSL_CMP_CTX_set1_clCert() sets the client certificate in the given B<ctx>.
+The public key of this B<clCert> must correspond to
+the private key set via B<OSSL_CMP_CTX_set1_pkey()>.
+When using signature-based protection of CMP request messages
+this "protection certificate" will be included first in the extraCerts field.
+The subject of this B<clCert> will be used as the "sender" field
+of outgoing CMP messages, with the fallback being
+the B<subjectName> set via B<OSSL_CMP_CTX_set1_subjectName()>.
+The B<cert> argument may be NULL to clear the entry.
+
+OSSL_CMP_CTX_set1_pkey() sets the private key corresponding to
+the client certificate B<clCert> set via B<OSSL_CMP_CTX_set1_clCert()>.
+This key is used create signature-based protection (protectionAlg = MSG_SIG_ALG)
+of outgoing messages
+unless a PBM secret has been set via B<OSSL_CMP_CTX_set1_secretValue()>.
+The B<pkey> argument may be NULL to clear the entry.
+
+OSSL_CMP_CTX_set1_secretValue() sets the byte string B<sec> with length B<len>
+as PBM secret in the given B<ctx> or clears it if the B<sec> argument is NULL.
+If present, this secret is used to create PBM-based protection of outgoing
+messages and to verify any PBM-based protection of incoming messages
+(protectionAlg = MSG_MAC_ALG). PBM stands for Password-Based MAC.
+PBM-based protection takes precedence over signature-based protection.
+
+OSSL_CMP_CTX_set1_referenceValue() sets the given referenceValue B<ref> with
+length B<len> in the given B<ctx> or clears it if the B<ref> argument is NULL.
+According to RFC 4210 section 5.1.1, if no value for the "sender" field in
+CMP message headers can be determined (i.e., no B<clCert> and no B<subjectName>
+is given) then the "sender" field will contain the NULL-DN
+and the senderKID field of the CMP message header must be set.
+When signature-based protection is used the senderKID will be set to
+the subjectKeyIdentifier of the <clCert> as far as present.
+If not present or when PBM-based protection is used
+the B<ref> value is taken as the fallback value for the senderKID.
OSSL_CMP_CTX_set1_recipient() sets the recipient name that will be used in the
PKIHeader of a request message, i.e. the X509 name of the (CA) server.
+++ /dev/null
-=pod
-
-=head1 NAME
-
-OSSL_CMP_CTX_snprint_PKIStatus
-- function(s) for managing the CMP PKIStatus
-
-=head1 SYNOPSIS
-
- #include <openssl/cmp.h>
-
- char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf, int bufsize);
-
-=head1 DESCRIPTION
-
-This is the PKIStatus API for using CMP (Certificate Management Protocol) with
-OpenSSL.
-
-OSSL_CMP_CTX_snprint_PKIStatus() takes the PKIStatusInfo components contained
-in the given CMP context and places a human-readable string created from them
-in the given buffer, with the given maximal length.
-On success it returns a copy of the buffer pointer containing the string.
-
-=head1 NOTES
-
-CMP is defined in RFC 4210 (and CRMF in RFC 4211).
-
-=head1 RETURN VALUES
-
-OSSL_CMP_CTX_snprint_PKIStatus()
-returns the intended pointer value as described above or NULL on error.
-
-=head1 HISTORY
-
-The OpenSSL CMP support was added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
=head1 NAME
-OSSL_CMP_MSG_get0_header
+OSSL_CMP_MSG_get0_header,
+OSSL_d2i_CMP_MSG_bio,
+OSSL_i2d_CMP_MSG_bio
- function(s) manipulating CMP messages
=head1 SYNOPSIS
#include <openssl/cmp.h>
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
+ OSSL_CMP_MSG *OSSL_d2i_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg);
+ int OSSL_i2d_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg);
=head1 DESCRIPTION
OSSL_CMP_MSG_get0_header returns the header of the given CMP message.
+OSSL_d2i_CMP_MSG_bio parses an ASN.1-encoded OSSL_CMP_MSG from the BIO I<bio>.
+It assigns a pointer to the new structure to I<*msg> if I<msg> is not NULL.
+
+OSSL_i2d_CMP_MSG_bio writes the OSSL_CMP_MSG I<msg> in ASN.1 encoding to BIO I<bio>.
+
=head1 NOTES
CMP is defined in RFC 4210.
=head1 RETURN VALUES
-CMP_MSG_get0_header() returns the intended pointer value as described above
+OSSL_CMP_MSG_get0_header() returns the intended pointer value as described above
or NULL if the respective entry does not exist and on error.
+OSSL_d2i_CMP_MSG_bio() returns the parsed message or NULL on error.
+
+OSSL_i2d_CMP_MSG_bio() returns 1 on success or 0 on error.
+
=head1 HISTORY
The OpenSSL CMP support was added in OpenSSL 3.0.
--- /dev/null
+=pod
+
+=head1 NAME
+
+OSSL_CMP_SRV_process_request,
+OSSL_CMP_CTX_server_perform,
+OSSL_CMP_SRV_CTX_new,
+OSSL_CMP_SRV_CTX_free,
+OSSL_CMP_SRV_cert_request_cb_t,
+OSSL_CMP_SRV_rr_cb_t,
+OSSL_CMP_SRV_certConf_cb_t,
+OSSL_CMP_SRV_genm_cb_t,
+OSSL_CMP_SRV_error_cb_t,
+OSSL_CMP_SRV_pollReq_cb_t,
+OSSL_CMP_SRV_CTX_init,
+OSSL_CMP_SRV_CTX_get0_cmp_ctx,
+OSSL_CMP_SRV_CTX_get0_custom_ctx,
+OSSL_CMP_SRV_CTX_set_send_unprotected_errors,
+OSSL_CMP_SRV_CTX_set_accept_unprotected,
+OSSL_CMP_SRV_CTX_set_accept_raverified,
+OSSL_CMP_SRV_CTX_set_grant_implicit_confirm
+- generic functions to set up and control a CMP server
+
+=head1 SYNOPSIS
+
+ #include <openssl/cmp.h>
+
+ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req);
+ OSSL_CMP_MSG *OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
+ const OSSL_CMP_MSG *req);
+ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void);
+ void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx);
+
+ typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t)(
+ OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ int certReqId,
+ const OSSL_CRMF_MSG *crm,
+ const X509_REQ *p10cr,
+ X509 **certOut,
+ STACK_OF(X509) **chainOut,
+ STACK_OF(X509) **caPubs);
+ typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_rr_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ const X509_NAME *issuer,
+ const ASN1_INTEGER *serial);
+ typedef int (*OSSL_CMP_SRV_genm_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ STACK_OF(OSSL_CMP_ITAV) *in,
+ STACK_OF(OSSL_CMP_ITAV) **out);
+ typedef void (*OSSL_CMP_SRV_error_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ const OSSL_CMP_PKISI *statusInfo,
+ const ASN1_INTEGER *errorCode,
+ const OSSL_CMP_PKIFREETEXT *errorDetails);
+ typedef int (*OSSL_CMP_SRV_certConf_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ int certReqId,
+ const ASN1_OCTET_STRING *certHash,
+ const OSSL_CMP_PKISI *si);
+ typedef int (*OSSL_CMP_SRV_pollReq_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ int certReqId,
+ OSSL_CMP_MSG **certReq,
+ int64_t *check_after);
+ int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
+ OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
+ OSSL_CMP_SRV_rr_cb_t process_rr,
+ OSSL_CMP_SRV_genm_cb_t process_genm,
+ OSSL_CMP_SRV_error_cb_t process_error,
+ OSSL_CMP_SRV_certConf_cb_t process_certConf,
+ OSSL_CMP_SRV_pollReq_cb_t process_pollReq);
+
+ OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
+ void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
+
+ int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val);
+ int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+ int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+ int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val);
+
+=head1 DESCRIPTION
+
+OSSL_CMP_SRV_process_request() implements the generic aspects of a CMP server.
+It does the typical generic checks on the given request message, calls
+the respective callback function (if present) for more specific processing,
+and then assembles a result message, which may be a CMP error message.
+
+OSSL_CMP_CTX_server_perform() is an interface to
+B<OSSL_CMP_SRV_process_request()> that can be used by a CMP client
+in the same way as B<OSSL_CMP_MSG_http_perform()>.
+The B<OSSL_CMP_SRV_CTX> must be set as B<transfer_cb_arg> of B<client_ctx>.
+
+OSSL_CMP_SRV_CTX_new() creates and initializes an OSSL_CMP_SRV_CTX structure
+and returns a pointer to it on success, NULL on error.
+
+OSSL_CMP_SRV_CTX_free() deletes the given B<srv_ctx>.
+
+OSSL_CMP_SRV_CTX_init() sets in the given B<srv_ctx> a custom server context
+pointer as well as callback functions performing the specific processing of CMP
+certificate requests, revocation requests, certificate confirmation requests,
+general messages, error messages, and poll requests.
+All arguments except B<srv_ctx> may be NULL.
+If a callback for some message type is not given this means that the respective
+type of CMP message is not supported by the server.
+
+OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns the B<OSSL_CMP_CTX> from the B<srv_ctx>.
+
+OSSL_CMP_SRV_CTX_get0_custom_ctx() returns the custom server context from
+B<srv_ctx> that has been set using B<OSSL_CMP_SRV_CTX_init>.
+
+OSSL_CMP_SRV_CTX_set_send_unprotected_errors() enables sending error messages
+and other forms of negative responses unprotected.
+
+OSSL_CMP_SRV_CTX_set_accept_unprotected() enables acceptance of requests
+without protection of with invalid protection.
+
+OSSL_CMP_SRV_CTX_set_accept_raverified() enables acceptance of ir/cr/kur
+messages with POPO 'RAVerified'.
+
+OSSL_CMP_SRV_CTX_set_grant_implicit_confirm() enables granting implicit
+confirmation of newly enrolled certificates if requested.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+OSSL_CMP_SRV_CTX_new() returns a B<OSSL_CMP_SRV_CTX> structure on success,
+NULL on error.
+
+OSSL_CMP_SRV_CTX_free() does not return a value.
+
+OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns a B<OSSL_CMP_CTX> structure on success,
+NULL on error.
+
+OSSL_CMP_SRV_CTX_get0_custom_ctx() returns the custom server context
+that has been set using B<OSSL_CMP_SRV_CTX_init>.
+
+All other functions return 1 on success, 0 on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+OSSL_CMP_STATUSINFO_new,
+OSSL_CMP_snprint_PKIStatusInfo,
+OSSL_CMP_CTX_snprint_PKIStatus
+- function(s) for managing the CMP PKIStatus
+
+=head1 SYNOPSIS
+
+ #include <openssl/cmp.h>
+
+ OSSL_CMP_PKISI *OSSL_CMP_STATUSINFO_new(int status, int fail_info,
+ const char *text);
+ char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo,
+ char *buf, size_t bufsize);
+ char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf,
+ size_t bufsize);
+
+=head1 DESCRIPTION
+
+This is the PKIStatus API for using CMP (Certificate Management Protocol) with
+OpenSSL.
+
+OSSL_CMP_STATUSINFO_new() creates a new PKIStatusInfo structure
+and fills in the given values.
+It sets the status field to B<status>,
+copies B<text> (unless it is NULL) to statusString,
+and interprets B<fail_info> as bit pattern for the failInfo field.
+
+OSSL_CMP_snprint_PKIStatusInfo() places a human-readable string
+representing the given statusInfo
+in the given buffer, with the given maximal length.
+
+OSSL_CMP_CTX_snprint_PKIStatus() places a human-readable string
+representing the PKIStatusInfo components of the CMP context B<ctx>
+in the given buffer, with the given maximal length.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+OSSL_CMP_STATUSINFO_new()
+returns a pointer to the structure on success, or NULL on error.
+
+OSSL_CMP_snprint_PKIStatusInfo() and
+OSSL_CMP_CTX_snprint_PKIStatus()
+return a copy of the buffer pointer containing the string or NULL on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+OSSL_CMP_X509_digest
+- CMP certificate utility functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/cmp_util.h>
+
+ ASN1_OCTET_STRING *OSSL_CMP_X509_digest(const X509 *cert);
+
+=head1 DESCRIPTION
+
+OSSL_CMP_X509_digest() calculates a digest of the given certificate
+using the same hash algorithm as in the certificate signature.
+
+=head1 RETURN VALUES
+
+OSSL_CMP_X509_digest() returns an ASN1_OCTET_STRING on success, else NULL.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
OCSP_SIGNATURE_new,
OCSP_SINGLERESP_free,
OCSP_SINGLERESP_new,
+OSSL_CMP_ITAV_dup,
OSSL_CMP_ITAV_free,
+OSSL_CMP_MSG_dup,
OSSL_CMP_MSG_it,
OSSL_CMP_MSG_free,
OSSL_CMP_PKIHEADER_free,
OSSL_CMP_PKIHEADER_it,
OSSL_CMP_PKIHEADER_new,
+OSSL_CMP_PKISI_dup,
OSSL_CMP_PKISI_free,
+OSSL_CMP_PKISI_it,
OSSL_CMP_PKISI_new,
OSSL_CMP_PKISTATUS_it,
OSSL_CRMF_CERTID_free,
d2i_OCSP_SINGLERESP,
d2i_OSSL_CMP_MSG,
d2i_OSSL_CMP_PKIHEADER,
+d2i_OSSL_CMP_PKISI,
d2i_OSSL_CRMF_CERTID,
d2i_OSSL_CRMF_CERTTEMPLATE,
d2i_OSSL_CRMF_ENCRYPTEDVALUE,
i2d_OCSP_SINGLERESP,
i2d_OSSL_CMP_MSG,
i2d_OSSL_CMP_PKIHEADER,
+i2d_OSSL_CMP_PKISI,
i2d_OSSL_CRMF_CERTID,
i2d_OSSL_CRMF_CERTTEMPLATE,
i2d_OSSL_CRMF_ENCRYPTEDVALUE,
typedef struct ossl_cmp_pkiheader_st OSSL_CMP_PKIHEADER;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKIHEADER)
typedef struct ossl_cmp_msg_st OSSL_CMP_MSG;
+DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG)
DECLARE_ASN1_ENCODE_FUNCTIONS(OSSL_CMP_MSG, OSSL_CMP_MSG, OSSL_CMP_MSG)
typedef struct ossl_cmp_certstatus_st OSSL_CMP_CERTSTATUS;
DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS)
typedef struct ossl_cmp_itav_st OSSL_CMP_ITAV;
+DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV)
DEFINE_STACK_OF(OSSL_CMP_ITAV)
typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT;
typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI;
+DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
+DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
DEFINE_STACK_OF(OSSL_CMP_PKISI)
typedef struct ossl_cmp_certrepmessage_st OSSL_CMP_CERTREPMESSAGE;
DEFINE_STACK_OF(OSSL_CMP_CERTREPMESSAGE)
int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path);
int OSSL_CMP_CTX_set1_serverName(OSSL_CMP_CTX *ctx, const char *name);
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port);
+# define OSSL_CMP_DEFAULT_PORT 80
int OSSL_CMP_CTX_set1_proxyName(OSSL_CMP_CTX *ctx, const char *name);
int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port);
-# define OSSL_CMP_DEFAULT_PORT 80
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb);
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg);
void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx);
X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx);
STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx);
STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx);
-/* support application-level CMP debugging in cmp.c: */
int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
const ASN1_OCTET_STRING *id);
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
const ASN1_OCTET_STRING *nonce);
/* from cmp_status.c */
-char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
+char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf,
size_t bufsize);
+char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo,
+ char *buf, size_t bufsize);
+OSSL_CMP_PKISI *
+OSSL_CMP_STATUSINFO_new(int status, int fail_info, const char *text);
/* from cmp_hdr.c */
-/* support application-level CMP debugging in cmp.c: */
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr);
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr);
/* from cmp_msg.c */
-/* support application-level CMP debugging in cmp.c: */
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
+OSSL_CMP_MSG *OSSL_d2i_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg);
+int OSSL_i2d_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg);
/* from cmp_vfy.c */
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg);
int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx,
X509_STORE *trusted_store, X509 *cert);
+/* from cmp_server.c */
+typedef struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_CTX;
+OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req);
+OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
+ const OSSL_CMP_MSG *req);
+OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void);
+void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx);
+typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t)
+ (OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req, int certReqId,
+ const OSSL_CRMF_MSG *crm, const X509_REQ *p10cr,
+ X509 **certOut, STACK_OF(X509) **chainOut, STACK_OF(X509) **caPubs);
+typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_rr_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ const X509_NAME *issuer,
+ const ASN1_INTEGER *serial);
+typedef int (*OSSL_CMP_SRV_genm_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ const STACK_OF(OSSL_CMP_ITAV) *in,
+ STACK_OF(OSSL_CMP_ITAV) **out);
+typedef void (*OSSL_CMP_SRV_error_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ const OSSL_CMP_PKISI *statusInfo,
+ const ASN1_INTEGER *errorCode,
+ const OSSL_CMP_PKIFREETEXT *errorDetails);
+typedef int (*OSSL_CMP_SRV_certConf_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req,
+ int certReqId,
+ const ASN1_OCTET_STRING *certHash,
+ const OSSL_CMP_PKISI *si);
+typedef int (*OSSL_CMP_SRV_pollReq_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req, int certReqId,
+ OSSL_CMP_MSG **certReq,
+ int64_t *check_after);
+int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
+ OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
+ OSSL_CMP_SRV_rr_cb_t process_rr,
+ OSSL_CMP_SRV_genm_cb_t process_genm,
+ OSSL_CMP_SRV_error_cb_t process_error,
+ OSSL_CMP_SRV_certConf_cb_t process_certConf,
+ OSSL_CMP_SRV_pollReq_cb_t process_pollReq);
+OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
+void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
+int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val);
+int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val);
+int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val);
+
# ifdef __cplusplus
}
# endif
-# endif /* !defined OPENSSL_NO_CMP */
-#endif /* !defined OPENSSL_CMP_H */
+# endif /* !defined(OPENSSL_NO_CMP) */
+#endif /* !defined(OPENSSL_CMP_H) */
/* use of the logging callback for outputting error queue */
void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn);
+ASN1_OCTET_STRING *OSSL_CMP_X509_digest(const X509 *cert);
+
# ifdef __cplusplus
}
# endif
-# endif /* !defined OPENSSL_NO_CMP */
-#endif /* !defined OPENSSL_CMP_UTIL_H */
+# endif /* !defined(OPENSSL_NO_CMP) */
+#endif /* !defined(OPENSSL_CMP_UTIL_H) */
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
# ifndef OPENSSL_NO_CMP
-# ifdef __cplusplus
+# ifdef __cplusplus
extern "C"
# endif
int ERR_load_CMP_strings(void);
/*
* CMP function codes.
*/
-# ifndef OPENSSL_NO_DEPRECATED_3_0
-# endif
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+# endif
/*
* CMP reason codes.
*/
# define CMP_R_ALGORITHM_NOT_SUPPORTED 139
# define CMP_R_BAD_REQUEST_ID 108
+# define CMP_R_CERTHASH_UNMATCHED 156
# define CMP_R_CERTID_NOT_FOUND 109
# define CMP_R_CERTIFICATE_NOT_FOUND 112
+# define CMP_R_CERTREQMSG_NOT_FOUND 157
# define CMP_R_CERTRESPONSE_NOT_FOUND 113
# define CMP_R_CERT_AND_KEY_DO_NOT_MATCH 114
# define CMP_R_ERROR_CALCULATING_PROTECTION 115
# define CMP_R_ERROR_CREATING_RP 125
# define CMP_R_ERROR_CREATING_RR 126
# define CMP_R_ERROR_PARSING_PKISTATUS 107
+# define CMP_R_ERROR_PROCESSING_MSG 158
# define CMP_R_ERROR_PROTECTING_MESSAGE 127
# define CMP_R_ERROR_SETTING_CERTHASH 128
+# define CMP_R_ERROR_TRANSFERRING_OUT 159
+# define CMP_R_ERROR_UNEXPECTED_CERTCONF 160
# define CMP_R_ERROR_VALIDATING_PROTECTION 140
# define CMP_R_FAILED_EXTRACTING_PUBKEY 141
# define CMP_R_FAILURE_OBTAINING_RANDOM 110
# define CMP_R_MISSING_PROTECTION 143
# define CMP_R_MISSING_SENDER_IDENTIFICATION 111
# define CMP_R_MISSING_TRUST_STORE 144
+# define CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED 161
# define CMP_R_MULTIPLE_SAN_SOURCES 102
# define CMP_R_NO_STDIO 194
# define CMP_R_NO_SUITABLE_SENDER_CERT 145
int OSSL_CRMF_MSG_set_validity(OSSL_CRMF_MSG *crm, time_t from, time_t to);
int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid);
-int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm);
+int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm);
int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, X509_EXTENSIONS *exts);
int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext);
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
int rid, int acceptRAVerified);
OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm);
-ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(OSSL_CRMF_CERTTEMPLATE *t);
-X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl);
+ASN1_INTEGER
+*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl);
+X509_NAME
+*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl);
X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid);
ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid);
int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
const X509_NAME *subject,
const X509_NAME *issuer,
const ASN1_INTEGER *serial);
-X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
- EVP_PKEY *pkey);
+X509
+*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
+ EVP_PKEY *pkey);
# ifdef __cplusplus
}
# endif
-# endif /* !defined OPENSSL_NO_CRMF */
-#endif /* !defined OPENSSL_CRMF_H */
+# endif /* !defined(OPENSSL_NO_CRMF) */
+#endif /* !defined(OPENSSL_CRMF_H) */
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
# ifndef OPENSSL_NO_CRMF
-# ifdef __cplusplus
+# ifdef __cplusplus
extern "C"
# endif
int ERR_load_CRMF_strings(void);
/*
* CRMF function codes.
*/
-# ifndef OPENSSL_NO_DEPRECATED_3_0
+# ifndef OPENSSL_NO_DEPRECATED_3_0
# define CRMF_F_CRMF_POPOSIGNINGKEY_INIT 0
# define CRMF_F_OSSL_CRMF_CERTID_GEN 0
# define CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL 0
# define CRMF_F_OSSL_CRMF_MSG_SET_VALIDITY 0
# define CRMF_F_OSSL_CRMF_PBMP_NEW 0
# define CRMF_F_OSSL_CRMF_PBM_NEW 0
-# endif
+# endif
/*
* CRMF reason codes.
# define CRMF_R_ITERATIONCOUNT_BELOW_100 108
# define CRMF_R_MALFORMED_IV 101
# define CRMF_R_NULL_ARGUMENT 109
+# define CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY 117
+# define CRMF_R_POPO_MISSING_PUBLIC_KEY 118
+# define CRMF_R_POPO_MISSING_SUBJECT 119
+# define CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED 120
# define CRMF_R_SETTING_MAC_ALGOR_FAILURE 110
# define CRMF_R_SETTING_OWF_ALGOR_FAILURE 111
# define CRMF_R_UNSUPPORTED_ALGORITHM 112
# define CRMF_R_UNSUPPORTED_CIPHER 114
# define CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO 115
# define CRMF_R_UNSUPPORTED_POPO_METHOD 116
-# define CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED 117
# endif
#endif
IF[{- !$disabled{cmp} -}]
PROGRAMS{noinst}=cmp_asn_test cmp_ctx_test cmp_status_test cmp_hdr_test \
- cmp_protect_test cmp_msg_test cmp_vfy_test
+ cmp_protect_test cmp_msg_test cmp_vfy_test \
+ cmp_server_test
ENDIF
SOURCE[cmp_asn_test]=cmp_asn_test.c cmp_testlib.c
INCLUDE[cmp_msg_test]=.. ../include ../apps/include
DEPEND[cmp_msg_test]=../libcrypto.a libtestutil.a
- SOURCE[cmp_vfy_test]=cmp_status_test.c cmp_testlib.c
+ SOURCE[cmp_vfy_test]=cmp_vfy_test.c cmp_testlib.c
INCLUDE[cmp_vfy_test]=.. ../include ../apps/include
DEPEND[cmp_vfy_test]=../libcrypto.a libtestutil.a
+ SOURCE[cmp_server_test]=cmp_server_test.c cmp_testlib.c
+ INCLUDE[cmp_server_test]=.. ../include ../apps/include
+ DEPEND[cmp_server_test]=../libcrypto.a libtestutil.a
+
# Internal test programs. These are essentially a collection of internal
# test routines. Some of them need to reach internal symbols that aren't
# available through the shared library (at least on Linux, Solaris, Windows
OSSL_CMP_severity level, const char *msg)
{
msg_total_size += strlen(msg);
+ TEST_note("total=%d len=%ld msg='%s'\n", msg_total_size, strlen(msg), msg);
return 1;
}
execute_HDR_set_and_check_implicitConfirm_test(CMP_HDR_TEST_FIXTURE
* fixture)
{
- return TEST_false(ossl_cmp_hdr_check_implicitConfirm(fixture->hdr))
+ return TEST_false(ossl_cmp_hdr_has_implicitConfirm(fixture->hdr))
&& TEST_true(ossl_cmp_hdr_set_implicitConfirm(fixture->hdr))
- && TEST_true(ossl_cmp_hdr_check_implicitConfirm(fixture->hdr));
+ && TEST_true(ossl_cmp_hdr_has_implicitConfirm(fixture->hdr));
}
static int test_HDR_set_and_check_implicit_confirm(void)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_error_new(fixture->cmp_ctx, fixture->si,
fixture->err_code,
- NULL /* fixture->free_text */,
- 0));
+ "details", 0));
}
static int execute_rr_create_test(CMP_MSG_TEST_FIXTURE *fixture)
static int test_cmp_create_error_msg(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
- fixture->si = ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection,
+ fixture->si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
OSSL_CMP_PKIFAILUREINFO_systemFailure,
NULL);
fixture->err_code = -1;
static int execute_rp_create(CMP_MSG_TEST_FIXTURE *fixture)
{
- OSSL_CMP_PKISI *si = ossl_cmp_statusinfo_new(33, 44, "a text");
+ OSSL_CMP_PKISI *si = OSSL_CMP_STATUSINFO_new(33, 44, "a text");
X509_NAME *issuer = X509_NAME_new();
ASN1_INTEGER *serial = ASN1_INTEGER_new();
OSSL_CRMF_CERTID *cid = NULL;
if (!TEST_ptr(ossl_cmp_revrepcontent_get_CertId(rpmsg->body->value.rp, 0)))
goto err;
- if (!TEST_ptr(ossl_cmp_revrepcontent_get_pkistatusinfo(rpmsg->body->
- value.rp, 0)))
+ if (!TEST_ptr(ossl_cmp_revrepcontent_get_pkisi(rpmsg->body->value.rp, 0)))
goto err;
res = 1;
--- /dev/null
+/*
+ * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright Nokia 2007-2020
+ * Copyright Siemens AG 2015-2020
+ *
+ * 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 "cmp_testlib.h"
+
+typedef struct test_fixture {
+ const char *test_case_name;
+ int expected;
+ OSSL_CMP_SRV_CTX *srv_ctx;
+ OSSL_CMP_MSG *req;
+} CMP_SRV_TEST_FIXTURE;
+
+static OSSL_CMP_MSG *request = NULL;
+
+static void tear_down(CMP_SRV_TEST_FIXTURE *fixture)
+{
+ OSSL_CMP_SRV_CTX_free(fixture->srv_ctx);
+ OPENSSL_free(fixture);
+}
+
+static CMP_SRV_TEST_FIXTURE *set_up(const char *const test_case_name)
+{
+ CMP_SRV_TEST_FIXTURE *fixture;
+
+ if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
+ return NULL;
+ fixture->test_case_name = test_case_name;
+ if (!TEST_ptr(fixture->srv_ctx = OSSL_CMP_SRV_CTX_new()))
+ goto err;
+ return fixture;
+
+ err:
+ tear_down(fixture);
+ return NULL;
+}
+
+static int dummy_errorCode = CMP_R_MULTIPLE_SAN_SOURCES; /* any reason code */
+
+static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *cert_req,
+ int certReqId,
+ const OSSL_CRMF_MSG *crm,
+ const X509_REQ *p10cr,
+ X509 **certOut,
+ STACK_OF(X509) **chainOut,
+ STACK_OF(X509) **caPubs)
+{
+ CMPerr(0, dummy_errorCode);
+ return NULL;
+}
+
+static int execute_test_handle_request(CMP_SRV_TEST_FIXTURE *fixture)
+{
+ OSSL_CMP_SRV_CTX *ctx = fixture->srv_ctx;
+ OSSL_CMP_CTX *client_ctx;
+ OSSL_CMP_CTX *cmp_ctx;
+ char *dummy_custom_ctx = "@test_dummy", *custom_ctx;
+ OSSL_CMP_MSG *rsp = NULL;
+ OSSL_CMP_ERRORMSGCONTENT *errorContent;
+ int res = 0;
+
+ if (!TEST_ptr(client_ctx = OSSL_CMP_CTX_new())
+ || !TEST_true(OSSL_CMP_CTX_set_transfer_cb_arg(client_ctx, ctx)))
+ goto end;
+
+ if (!TEST_true(OSSL_CMP_SRV_CTX_init(ctx, dummy_custom_ctx,
+ process_cert_request, NULL, NULL,
+ NULL, NULL, NULL))
+ || !TEST_ptr(custom_ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(ctx))
+ || !TEST_int_eq(strcmp(custom_ctx, dummy_custom_ctx), 0))
+ goto end;
+
+ if (!TEST_true(OSSL_CMP_SRV_CTX_set_send_unprotected_errors(ctx, 0))
+ || !TEST_true(OSSL_CMP_SRV_CTX_set_accept_unprotected(ctx, 0))
+ || !TEST_true(OSSL_CMP_SRV_CTX_set_accept_raverified(ctx, 1))
+ || !TEST_true(OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(ctx, 1)))
+ goto end;
+
+ if (!TEST_ptr(cmp_ctx = OSSL_CMP_SRV_CTX_get0_cmp_ctx(ctx))
+ || !OSSL_CMP_CTX_set1_referenceValue(cmp_ctx,
+ (unsigned char *)"server", 6)
+ || !OSSL_CMP_CTX_set1_secretValue(cmp_ctx,
+ (unsigned char *)"1234", 4))
+ goto end;
+
+ if (!TEST_ptr(rsp = OSSL_CMP_CTX_server_perform(client_ctx, fixture->req))
+ || !TEST_int_eq(ossl_cmp_msg_get_bodytype(rsp),
+ OSSL_CMP_PKIBODY_ERROR)
+ || !TEST_ptr(errorContent = rsp->body->value.error)
+ || !TEST_int_eq(ASN1_INTEGER_get(errorContent->errorCode),
+ dummy_errorCode))
+ goto end;
+
+ res = 1;
+
+ end:
+ OSSL_CMP_MSG_free(rsp);
+ OSSL_CMP_CTX_free(client_ctx);
+ return res;
+}
+
+static int test_handle_request(void)
+{
+ SETUP_TEST_FIXTURE(CMP_SRV_TEST_FIXTURE, set_up);
+ fixture->req = request;
+ fixture->expected = 1;
+ EXECUTE_TEST(execute_test_handle_request, tear_down);
+ return result;
+}
+
+void cleanup_tests(void)
+{
+ OSSL_CMP_MSG_free(request);
+ return;
+}
+
+int setup_tests(void)
+{
+ const char *request_f;
+
+ if (!test_skip_common_options()) {
+ TEST_error("Error parsing test options\n");
+ return 0;
+ }
+
+ if (!TEST_ptr(request_f = test_get_argument(0))) {
+ TEST_error("usage: cmp_server_test CR_protected_PBM_1234.der\n");
+ return 0;
+ }
+
+ if (!TEST_ptr(request = load_pkimsg(request_f))) {
+ cleanup_tests();
+ return 0;
+ }
+
+ /*
+ * this (indirectly) calls
+ * OSSL_CMP_SRV_CTX_new(),
+ * OSSL_CMP_SRV_CTX_free(),
+ * OSSL_CMP_CTX_server_perform(),
+ * OSSL_CMP_SRV_process_request(),
+ * OSSL_CMP_SRV_CTX_init(),
+ * OSSL_CMP_SRV_CTX_get0_cmp_ctx(),
+ * OSSL_CMP_SRV_CTX_get0_custom_ctx(),
+ * OSSL_CMP_SRV_CTX_set_send_unprotected_errors(),
+ * OSSL_CMP_SRV_CTX_set_accept_unprotected(),
+ * OSSL_CMP_SRV_CTX_set_accept_raverified(), and
+ * OSSL_CMP_SRV_CTX_set_grant_implicit_confirm()
+ */
+ ADD_TEST(test_handle_request);
+ return 1;
+}
ASN1_UTF8STRING *statusString = NULL;
int res = 0, i;
- if (!TEST_ptr(si = ossl_cmp_statusinfo_new(fixture->pkistatus,
+ if (!TEST_ptr(si = OSSL_CMP_STATUSINFO_new(fixture->pkistatus,
fixture->pkifailure,
fixture->text)))
goto end;
- status = ossl_cmp_pkisi_get_pkistatus(si);
+ status = ossl_cmp_pkisi_get_status(si);
if (!TEST_int_eq(fixture->pkistatus, status)
|| !TEST_str_eq(fixture->str, ossl_cmp_PKIStatus_to_string(status)))
goto end;
if (!TEST_ptr(statusString =
- sk_ASN1_UTF8STRING_value(ossl_cmp_pkisi_get0_statusstring(si),
+ sk_ASN1_UTF8STRING_value(ossl_cmp_pkisi_get0_statusString(si),
0))
|| !TEST_str_eq(fixture->text, (char *)statusString->data))
goto end;
goto end;
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++)
if (!TEST_int_eq((fixture->pkifailure >> i) & 1,
- ossl_cmp_pkisi_pkifailureinfo_check(si, i)))
+ ossl_cmp_pkisi_check_pkifailureinfo(si, i)))
goto end;
res = 1;
{
/*-
* this tests all of:
- * ossl_cmp_statusinfo_new()
- * ossl_cmp_pkisi_get_pkistatus()
+ * OSSL_CMP_STATUSINFO_new()
+ * ossl_cmp_pkisi_get_status()
* ossl_cmp_PKIStatus_to_string()
- * ossl_cmp_pkisi_get0_statusstring()
+ * ossl_cmp_pkisi_get0_statusString()
* ossl_cmp_pkisi_get_pkifailureinfo()
- * ossl_cmp_pkisi_pkifailureinfo_check()
+ * ossl_cmp_pkisi_check_pkifailureinfo()
*/
ADD_TEST(test_PKISI);
return 1;
return NULL;
}
X509_VERIFY_PARAM_set_time(X509_STORE_get0_param(ts), test_time_valid);
- X509_STORE_set_verify_cb(ts, OSSL_CMP_print_cert_verify_cb);
+ X509_STORE_set_verify_cb(ts, X509_STORE_CTX_print_verify_cb);
return fixture;
}
nonce_data, nonce_len))) {
tear_down((*fixture));
(*fixture) = NULL;
- }
- else if (trid_data != NULL) {
+ } else if (trid_data != NULL) {
ASN1_OCTET_STRING *trid = ASN1_OCTET_STRING_new();
if (trid == NULL
|| !ASN1_OCTET_STRING_set(trid, trid_data,
ts.tm_year += 10; /* February 18th 2028 */
test_time_after_expiration = mktime(&ts);
+ if (!test_skip_common_options()) {
+ TEST_error("Error parsing test options\n");
+ return 0;
+ }
+
RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH);
if (!TEST_ptr(server_f = test_get_argument(0))
|| !TEST_ptr(client_f = test_get_argument(1))
--- /dev/null
+#! /usr/bin/env perl
+# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright Nokia 2007-2020
+# Copyright Siemens AG 2015-2020
+#
+# 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
+
+use strict;
+use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test::Utils;
+
+setup("test_cmp_server");
+
+plan skip_all => "This test is not supported in a no-cmp build"
+ if disabled("cmp");
+
+plan skip_all => "This test is not supported in a no-ec build"
+ if disabled("ec");
+
+plan tests => 1;
+
+ok(run(test(["cmp_server_test",
+ data_file("CR_protected_PBM_1234.der")])));
OSSL_SELF_TEST_oncorrupt_byte ? 3_0_0 EXIST::FUNCTION:
OSSL_SELF_TEST_onend ? 3_0_0 EXIST::FUNCTION:
OSSL_PROVIDER_set_default_search_path ? 3_0_0 EXIST::FUNCTION:
+OSSL_CMP_MSG_dup ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_ITAV_dup ? 3_0_0 EXIST::FUNCTION:CMP
+d2i_OSSL_CMP_PKISI ? 3_0_0 EXIST::FUNCTION:CMP
+i2d_OSSL_CMP_PKISI ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_PKISI_free ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_PKISI_new ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_PKISI_it ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_PKISI_dup ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_snprint_PKIStatusInfo ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_STATUSINFO_new ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_d2i_CMP_MSG_bio ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_i2d_CMP_MSG_bio ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_process_request ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_CTX_server_perform ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_new ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_free ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_init ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_get0_cmp_ctx ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_get0_custom_ctx ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_set_send_unprotected_errors ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_set_accept_unprotected ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_set_accept_raverified ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_SRV_CTX_set_grant_implicit_confirm ? 3_0_0 EXIST::FUNCTION:CMP
+OSSL_CMP_X509_digest ? 3_0_0 EXIST::FUNCTION:CMP
OSSL_cmp_certConf_cb_t datatype
OSSL_cmp_log_cb_t datatype
OSSL_cmp_transfer_cb_t datatype
+OSSL_CMP_SRV_cert_request_cb_t datatype
+OSSL_CMP_SRV_rr_cb_t datatype
+OSSL_CMP_SRV_certConf_cb_t datatype
+OSSL_CMP_SRV_genm_cb_t datatype
+OSSL_CMP_SRV_error_cb_t datatype
+OSSL_CMP_SRV_pollReq_cb_t datatype
OSSL_PARAM_TYPE define
OSSL_PARAM_octet_ptr define
OSSL_PARAM_octet_string define