chunk 6 of CMP contribution to OpenSSL

Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10297)
This commit is contained in:
Dr. David von Oheimb 2019-11-05 09:56:59 +01:00 committed by Matt Caswell
parent 0402c90ff9
commit 3dbc5156b0
39 changed files with 2963 additions and 110 deletions

View File

@ -1,3 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
cmp_status.c cmp_hdr.c
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c

View File

@ -946,7 +946,8 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
* Sets a Boolean or integer option of the context to the "val" arg.
* Returns 1 on success, 0 on error
*/
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) {
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
{
int min_val;
if (ctx == NULL) {
@ -1049,7 +1050,8 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) {
* Reads a Boolean or integer option value from the context.
* Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON)
*/
int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) {
int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
{
if (ctx == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return -1;

View File

@ -1,7 +1,6 @@
/*
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Nokia 2007-2019
* Copyright Siemens AG 2015-2019
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-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
@ -15,17 +14,69 @@
#ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA CMP_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"},
{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_CERTRESPONSE_NOT_FOUND),
"certresponse not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH),
"cert and key do not match"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CALCULATING_PROTECTION),
"error calculating protection"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTCONF),
"error creating certconf"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREP),
"error creating certrep"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_ERROR),
"error creating error"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENM),
"error creating genm"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENP),
"error creating genp"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_P10CR),
"error creating p10cr"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_PKICONF),
"error creating pkiconf"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREP),
"error creating pollrep"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREQ),
"error creating pollreq"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RP), "error creating rp"},
{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_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_FAILURE_OBTAINING_RANDOM),
"failure obtaining random"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE),
"fail info out of range"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES),
"multiple san sources"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION),
"missing key input for creating protection"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY),
"missing private key"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SENDER_IDENTIFICATION),
"missing sender identification"},
{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"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NULL_ARGUMENT), "null argument"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND),
"pkistatusinfo not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
"unknown algorithm id"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM),
"unsupported algorithm"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
"unsupported key type"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID),
"wrong algorithm oid"},
{0, NULL}
};

View File

@ -42,7 +42,7 @@ struct ossl_cmp_ctx_st {
int proxyPort;
int msgtimeout; /* max seconds to wait for each CMP message round trip */
int totaltimeout; /* maximum number seconds an enrollment may take, incl. */
/* attempts polling for a response if a 'waiting' PKIStatus is received */
/* attempts polling for a response if a 'waiting' PKIStatus is received */
time_t end_time; /* session start time + totaltimeout */
OSSL_cmp_http_cb_t http_cb;
void *http_cb_arg; /* allows to store optional argument to cb */
@ -279,6 +279,7 @@ struct ossl_cmp_pkisi_st {
} /* OSSL_CMP_PKISI */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
/*-
* RevReqContent ::= SEQUENCE OF RevDetails
@ -526,6 +527,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_GENREPCONTENT)
* certConf [24] CertConfirmContent, --Certificate confirm
* pollReq [25] PollReqContent, --Polling request
* pollRep [26] PollRepContent --Polling response
* }
*/
typedef struct ossl_cmp_pkibody_st {
int type;
@ -679,6 +681,13 @@ DECLARE_ASN1_FUNCTIONS(CMP_PROTECTEDPART)
* }
*/
/*
* 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
*/
@ -752,4 +761,91 @@ int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
# define OSSL_CMP_SENDERNONCE_LENGTH 16
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
/* from cmp_msg.c */
/* OSSL_CMP_MSG bodytype ASN.1 choice IDs */
# define OSSL_CMP_PKIBODY_IR 0
# define OSSL_CMP_PKIBODY_IP 1
# define OSSL_CMP_PKIBODY_CR 2
# define OSSL_CMP_PKIBODY_CP 3
# define OSSL_CMP_PKIBODY_P10CR 4
# define OSSL_CMP_PKIBODY_POPDECC 5
# define OSSL_CMP_PKIBODY_POPDECR 6
# define OSSL_CMP_PKIBODY_KUR 7
# define OSSL_CMP_PKIBODY_KUP 8
# define OSSL_CMP_PKIBODY_KRR 9
# define OSSL_CMP_PKIBODY_KRP 10
# define OSSL_CMP_PKIBODY_RR 11
# define OSSL_CMP_PKIBODY_RP 12
# define OSSL_CMP_PKIBODY_CCR 13
# define OSSL_CMP_PKIBODY_CCP 14
# define OSSL_CMP_PKIBODY_CKUANN 15
# define OSSL_CMP_PKIBODY_CANN 16
# define OSSL_CMP_PKIBODY_RANN 17
# define OSSL_CMP_PKIBODY_CRLANN 18
# define OSSL_CMP_PKIBODY_PKICONF 19
# define OSSL_CMP_PKIBODY_NESTED 20
# define OSSL_CMP_PKIBODY_GENM 21
# define OSSL_CMP_PKIBODY_GENP 22
# define OSSL_CMP_PKIBODY_ERROR 23
# define OSSL_CMP_PKIBODY_CERTCONF 24
# define OSSL_CMP_PKIBODY_POLLREQ 25
# define OSSL_CMP_PKIBODY_POLLREP 26
# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP
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_msg_create(OSSL_CMP_CTX *ctx, int bodytype);
OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int bodytype,
int err_code);
OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
int certReqId, OSSL_CMP_PKISI *si,
X509 *cert, STACK_OF(X509) *chain,
STACK_OF(X509) *caPubs, int encrypted,
int unprotectedErrors);
OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
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);
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);
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_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);
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_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep,
int rsid);
OSSL_CMP_POLLREP *
ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
int rid);
OSSL_CMP_CERTRESPONSE *
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crepmsg,
int rid);
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,
const ASN1_OCTET_STRING *secret,
EVP_PKEY *pkey);
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */

996
crypto/cmp/cmp_msg.c Normal file
View File

@ -0,0 +1,996 @@
/*
* 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
*/
/* CMP functions for PKIMessage construction */
#include "cmp_local.h"
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h>
#include <openssl/x509.h>
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg)
{
if (msg == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return NULL;
}
return msg->header;
}
const char *ossl_cmp_bodytype_to_string(int type)
{
static const char *type_names[] = {
"IR", "IP", "CR", "CP", "P10CR",
"POPDECC", "POPDECR", "KUR", "KUP",
"KRR", "KRP", "RR", "RP", "CCR", "CCP",
"CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED",
"GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP",
};
if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX)
return "illegal body type";
return type_names[type];
}
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type)
{
if (!ossl_assert(msg != NULL && msg->body != NULL))
return 0;
msg->body->type = type;
return 1;
}
int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg)
{
if (!ossl_assert(msg != NULL && msg->body != NULL))
return -1;
return msg->body->type;
}
/* Add an extension to the referenced extension stack, which may be NULL */
static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex)
{
X509_EXTENSION *ext;
int res;
if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */
return 0;
if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL)
return 0;
res = X509v3_add_ext(pexts, ext, 0) != NULL;
X509_EXTENSION_free(ext);
return res;
}
/* Add a CRL revocation reason code to extension stack, which may be NULL */
static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code)
{
ASN1_ENUMERATED *val = ASN1_ENUMERATED_new();
int res = 0;
if (val != NULL && ASN1_ENUMERATED_set(val, reason_code))
res = add1_extension(pexts, NID_crl_reason, 0 /* non-critical */, val);
ASN1_ENUMERATED_free(val);
return res;
}
OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype)
{
OSSL_CMP_MSG *msg = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
if ((msg = OSSL_CMP_MSG_new()) == NULL)
return NULL;
if (!ossl_cmp_hdr_init(ctx, msg->header)
|| !ossl_cmp_msg_set_bodytype(msg, bodytype))
goto err;
if (ctx->geninfo_ITAVs != NULL
&& !ossl_cmp_hdr_generalInfo_push1_items(msg->header,
ctx->geninfo_ITAVs))
goto err;
switch (bodytype) {
case OSSL_CMP_PKIBODY_IR:
case OSSL_CMP_PKIBODY_CR:
case OSSL_CMP_PKIBODY_KUR:
if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_P10CR:
if (ctx->p10CSR == NULL) {
CMPerr(0, CMP_R_ERROR_CREATING_P10CR);
goto err;
}
if ((msg->body->value.p10cr = X509_REQ_dup(ctx->p10CSR)) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_IP:
case OSSL_CMP_PKIBODY_CP:
case OSSL_CMP_PKIBODY_KUP:
if ((msg->body->value.ip = OSSL_CMP_CERTREPMESSAGE_new()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_RR:
if ((msg->body->value.rr = sk_OSSL_CMP_REVDETAILS_new_null()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_RP:
if ((msg->body->value.rp = OSSL_CMP_REVREPCONTENT_new()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_CERTCONF:
if ((msg->body->value.certConf =
sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_PKICONF:
if ((msg->body->value.pkiconf = ASN1_TYPE_new()) == NULL)
goto err;
ASN1_TYPE_set(msg->body->value.pkiconf, V_ASN1_NULL, NULL);
return msg;
case OSSL_CMP_PKIBODY_POLLREQ:
if ((msg->body->value.pollReq = sk_OSSL_CMP_POLLREQ_new_null()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_POLLREP:
if ((msg->body->value.pollRep = sk_OSSL_CMP_POLLREP_new_null()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_GENM:
case OSSL_CMP_PKIBODY_GENP:
if ((msg->body->value.genm = sk_OSSL_CMP_ITAV_new_null()) == NULL)
goto err;
return msg;
case OSSL_CMP_PKIBODY_ERROR:
if ((msg->body->value.error = OSSL_CMP_ERRORMSGCONTENT_new()) == NULL)
goto err;
return msg;
default:
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
goto err;
}
err:
OSSL_CMP_MSG_free(msg);
return NULL;
}
#define HAS_SAN(ctx) \
(sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
|| OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
int bodytype)
{
if (ctx->subjectName != NULL)
return ctx->subjectName;
if (refcert != NULL
&& (bodytype == OSSL_CMP_PKIBODY_KUR || !HAS_SAN(ctx)))
/*
* For KUR, copy subjectName from reference certificate.
* For IR or CR, do the same only if there is no subjectAltName.
*/
return X509_get_subject_name(refcert);
return NULL;
}
/*
* 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)
{
OSSL_CRMF_MSG *crm = NULL;
X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->clCert;
/* refcert defaults to current client cert */
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
|| (bodytype == OSSL_CMP_PKIBODY_KUR && refcert == NULL)) {
CMPerr(0, CMP_R_INVALID_ARGS);
return NULL;
}
if ((crm = OSSL_CRMF_MSG_new()) == NULL)
return NULL;
if (!OSSL_CRMF_MSG_set_certReqId(crm, rid)
/*
* fill certTemplate, corresponding to CertificationRequestInfo
* of PKCS#10. The rkey param cannot be NULL so far -
* it could be NULL if centralized key creation was supported
*/
|| !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey,
subject, ctx->issuer,
NULL/* serial */))
goto err;
if (ctx->days != 0) {
time_t notBefore, notAfter;
notBefore = time(NULL);
notAfter = notBefore + 60 * 60 * 24 * ctx->days;
if (!OSSL_CRMF_MSG_set_validity(crm, notBefore, notAfter))
goto err;
}
/* extensions */
if (refcert != NULL && !ctx->SubjectAltName_nodefault)
default_sans = X509V3_get_d2i(X509_get0_extensions(refcert),
NID_subject_alt_name, NULL, NULL);
/* exts are copied from ctx to allow reuse */
if (ctx->reqExtensions != NULL) {
exts = sk_X509_EXTENSION_deep_copy(ctx->reqExtensions,
X509_EXTENSION_dup,
X509_EXTENSION_free);
if (exts == NULL)
goto err;
}
if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0
&& !add1_extension(&exts, NID_subject_alt_name,
crit, ctx->subjectAltNames))
goto err;
if (!HAS_SAN(ctx) && default_sans != NULL
&& !add1_extension(&exts, NID_subject_alt_name, crit, default_sans))
goto err;
if (ctx->policies != NULL
&& !add1_extension(&exts, NID_certificate_policies,
ctx->setPoliciesCritical, ctx->policies))
goto err;
if (!OSSL_CRMF_MSG_set0_extensions(crm, exts))
goto err;
exts = NULL;
/* end fill certTemplate, now set any controls */
/* for KUR, set OldCertId according to D.6 */
if (bodytype == OSSL_CMP_PKIBODY_KUR) {
OSSL_CRMF_CERTID *cid =
OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert),
X509_get_serialNumber(refcert));
int ret;
if (cid == NULL)
goto err;
ret = OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm, cid);
OSSL_CRMF_CERTID_free(cid);
if (ret == 0)
goto err;
}
goto end;
err:
OSSL_CRMF_MSG_free(crm);
crm = NULL;
end:
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
sk_GENERAL_NAME_pop_free(default_sans, GENERAL_NAME_free);
return crm;
}
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);
return NULL;
}
if ((msg = ossl_cmp_msg_create(ctx, type)) == NULL)
goto err;
/* header */
if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header))
goto err;
/* body */
/* For P10CR the content has already been set in OSSL_CMP_MSG_create */
if (type != OSSL_CMP_PKIBODY_P10CR) {
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))
goto err;
crm = NULL;
/* TODO: here optional 2nd certreqmsg could be pushed to the stack */
}
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, err_code);
OSSL_CRMF_MSG_free(crm);
OSSL_CMP_MSG_free(msg);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
int certReqId, OSSL_CMP_PKISI *si,
X509 *cert, STACK_OF(X509) *chain,
STACK_OF(X509) *caPubs, int encrypted,
int unprotectedErrors)
{
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_CERTREPMESSAGE *repMsg = NULL;
OSSL_CMP_CERTRESPONSE *resp = NULL;
int status = -1;
if (!ossl_assert(ctx != NULL && si != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, bodytype)) == NULL)
goto err;
repMsg = msg->body->value.ip; /* value.ip is same for cp and kup */
/* header */
if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header))
goto err;
/* body */
if ((resp = OSSL_CMP_CERTRESPONSE_new()) == NULL)
goto err;
OSSL_CMP_PKISI_free(resp->status);
if ((resp->status = OSSL_CMP_PKISI_dup(si)) == NULL
|| !ASN1_INTEGER_set(resp->certReqId, certReqId))
goto err;
status = ossl_cmp_pkisi_get_pkistatus(resp->status);
if (status != OSSL_CMP_PKISTATUS_rejection
&& status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) {
if (encrypted) {
CMPerr(0, CMP_R_INVALID_ARGS);
goto err;
}
if ((resp->certifiedKeyPair = OSSL_CMP_CERTIFIEDKEYPAIR_new())
== NULL)
goto err;
resp->certifiedKeyPair->certOrEncCert->type =
OSSL_CMP_CERTORENCCERT_CERTIFICATE;
if (!X509_up_ref(cert))
goto err;
resp->certifiedKeyPair->certOrEncCert->value.certificate = cert;
}
if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg->response, resp))
goto err;
resp = NULL;
/* TODO: here optional 2nd certrep could be pushed to the stack */
if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL
&& (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL)
goto err;
if (chain != NULL
&& !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0))
goto err;
if (!unprotectedErrors
|| ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_CERTREP);
OSSL_CMP_CERTRESPONSE_free(resp);
OSSL_CMP_MSG_free(msg);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx)
{
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_REVDETAILS *rd;
if (!ossl_assert(ctx != NULL && ctx->oldCert != NULL))
return NULL;
if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL)
goto err;
/* Fill the template from the contents of the certificate to be revoked */
if (!OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails,
NULL/* pubkey would be redundant */,
NULL/* subject would be redundant */,
X509_get_issuer_name(ctx->oldCert),
X509_get_serialNumber(ctx->oldCert)))
goto err;
/* revocation reason code is optional */
if (ctx->revocationReason != CRL_REASON_NONE
&& !add_crl_reason_extension(&rd->crlEntryDetails,
ctx->revocationReason))
goto err;
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL)
goto err;
if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd))
goto err;
rd = NULL;
/*
* TODO: the Revocation Passphrase according to section 5.3.19.9 could be
* set here if set in ctx
*/
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_RR);
OSSL_CMP_MSG_free(msg);
OSSL_CMP_REVDETAILS_free(rd);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
OSSL_CRMF_CERTID *cid, int unprot_err)
{
OSSL_CMP_REVREPCONTENT *rep = NULL;
OSSL_CMP_PKISI *si1 = NULL;
OSSL_CRMF_CERTID *cid_copy = NULL;
OSSL_CMP_MSG *msg = NULL;
if (!ossl_assert(ctx != NULL && si != NULL && cid != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL)
goto err;
rep = msg->body->value.rp;
if ((si1 = OSSL_CMP_PKISI_dup(si)) == NULL)
goto err;
if (!sk_OSSL_CMP_PKISI_push(rep->status, si1)) {
OSSL_CMP_PKISI_free(si1);
goto err;
}
if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL)
goto err;
if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL)
goto err;
if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) {
OSSL_CRMF_CERTID_free(cid_copy);
goto err;
}
if (!unprot_err
|| ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_RP);
OSSL_CMP_MSG_free(msg);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx)
{
OSSL_CMP_MSG *msg;
if (!ossl_assert(ctx != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL)
goto err;
if (ossl_cmp_msg_protect(ctx, msg))
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
OSSL_CMP_MSG_free(msg);
return NULL;
}
int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav)
{
int bodytype;
if (!ossl_assert(msg != NULL && itav != NULL))
return 0;
bodytype = ossl_cmp_msg_get_bodytype(msg);
if (bodytype != OSSL_CMP_PKIBODY_GENM
&& bodytype != OSSL_CMP_PKIBODY_GENP) {
CMPerr(0, CMP_R_INVALID_ARGS);
return 0;
}
/* value.genp has the same structure, so this works for genp as well */
return OSSL_CMP_ITAV_push0_stack_item(&msg->body->value.genm, itav);
}
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i;
OSSL_CMP_ITAV *itav = NULL;
if (!ossl_assert(msg != NULL))
return 0;
for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
if ((itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs,i))) == NULL)
return 0;
if (!ossl_cmp_msg_gen_push0_ITAV(msg, itav)) {
OSSL_CMP_ITAV_free(itav);
return 0;
}
}
return 1;
}
/*
* 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)
{
OSSL_CMP_MSG *msg = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL)
return NULL;
if (ctx->genm_ITAVs != NULL
&& !ossl_cmp_msg_gen_push1_ITAVs(msg, ctx->genm_ITAVs))
goto err;
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, err_code);
OSSL_CMP_MSG_free(msg);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
{
return gen_new(ctx, OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
}
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx)
{
return gen_new(ctx, 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)
{
OSSL_CMP_MSG *msg = NULL;
if (!ossl_assert(ctx != NULL && si != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL)
goto err;
OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo);
if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si))
== NULL)
goto err;
if (errorCode >= 0) {
if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL)
goto err;
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)
goto err;
if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_ERROR);
OSSL_CMP_MSG_free(msg);
return NULL;
}
/*
* 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.
*/
int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
const X509 *cert)
{
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);
return 0;
}
return 1;
err:
CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH);
return 0;
}
/*
* TODO: handle potential 2nd certificate when signing and encrypting
* certificates have been requested/received
*/
OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
const char *text)
{
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_CERTSTATUS *certStatus = NULL;
OSSL_CMP_PKISI *sinfo;
if (!ossl_assert(ctx != NULL && ctx->newCert != NULL))
return NULL;
if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) {
CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE);
return NULL;
}
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_CERTCONF)) == NULL)
goto err;
if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL)
goto err;
/* consume certStatus into msg right away so it gets deallocated with msg */
if (!sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus))
goto err;
/* set the ID of the certReq */
if (!ASN1_INTEGER_set(certStatus->certReqId, OSSL_CMP_CERTREQID))
goto err;
/*
* 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))
goto err;
/*
* For any particular CertStatus, omission of the statusInfo field
* indicates ACCEPTANCE of the specified certificate. Alternatively,
* explicit status details (with respect to acceptance or rejection) MAY
* be provided in the statusInfo field, perhaps for auditing purposes at
* 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);
if (sinfo == NULL)
goto err;
certStatus->statusInfo = sinfo;
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF);
OSSL_CMP_MSG_free(msg);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid)
{
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_POLLREQ *preq = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL)
goto err;
/* TODO: support multiple cert request IDs to poll */
if ((preq = OSSL_CMP_POLLREQ_new()) == NULL
|| !ASN1_INTEGER_set(preq->certReqId, crid)
|| !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq))
goto err;
preq = NULL;
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ);
OSSL_CMP_POLLREQ_free(preq);
OSSL_CMP_MSG_free(msg);
return NULL;
}
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
int64_t poll_after)
{
OSSL_CMP_MSG *msg;
OSSL_CMP_POLLREP *prep;
if (!ossl_assert(ctx != NULL))
return NULL;
if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREP)) == NULL)
goto err;
if ((prep = OSSL_CMP_POLLREP_new()) == NULL)
goto err;
if (!sk_OSSL_CMP_POLLREP_push(msg->body->value.pollRep, prep))
goto err;
if (!ASN1_INTEGER_set(prep->certReqId, crid))
goto err;
if (!ASN1_INTEGER_set_int64(prep->checkAfter, poll_after))
goto err;
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
return msg;
err:
CMPerr(0, CMP_R_ERROR_CREATING_POLLREP);
OSSL_CMP_MSG_free(msg);
return NULL;
}
/*-
* returns the status field of the RevRepContent with the given
* request/sequence id inside a revocation response.
* RevRepContent has the revocation statuses in same order as they were sent in
* RevReqContent.
* returns NULL on error
*/
OSSL_CMP_PKISI *
ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
{
OSSL_CMP_PKISI *status;
if (!ossl_assert(rrep != NULL))
return NULL;
if ((status = sk_OSSL_CMP_PKISI_value(rrep->status, rsid)) != NULL)
return status;
CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND);
return NULL;
}
/*
* returns the CertId field in the revCerts part of the RevRepContent
* with the given request/sequence id inside a revocation response.
* RevRepContent has the CertIds in same order as they were sent in
* RevReqContent.
* returns NULL on error
*/
OSSL_CRMF_CERTID *
ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
{
OSSL_CRMF_CERTID *cid = NULL;
if (!ossl_assert(rrep != NULL))
return NULL;
if ((cid = sk_OSSL_CRMF_CERTID_value(rrep->revCerts, rsid)) != NULL)
return cid;
CMPerr(0, CMP_R_CERTID_NOT_FOUND);
return NULL;
}
static int suitable_rid(const ASN1_INTEGER *certReqId, int rid)
{
int trid;
if (rid == -1)
return 1;
trid = ossl_cmp_asn1_get_int(certReqId);
if (trid == -1) {
CMPerr(0, CMP_R_BAD_REQUEST_ID);
return 0;
}
return rid == trid;
}
static void add_expected_rid(int rid)
{
char str[DECIMAL_SIZE(rid) + 1];
BIO_snprintf(str, sizeof(str), "%d", rid);
ERR_add_error_data(2, "expected certReqId = ", str);
}
/*
* returns a pointer to the PollResponse with the given CertReqId
* (or the first one in case -1) inside a PollRepContent
* returns NULL on error or if no suitable PollResponse available
*/
OSSL_CMP_POLLREP *
ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
int rid)
{
OSSL_CMP_POLLREP *pollRep = NULL;
int i;
if (!ossl_assert(prc != NULL))
return NULL;
for (i = 0; i < sk_OSSL_CMP_POLLREP_num(prc); i++) {
pollRep = sk_OSSL_CMP_POLLREP_value(prc, i);
if (suitable_rid(pollRep->certReqId, rid))
return pollRep;
}
CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND);
add_expected_rid(rid);
return NULL;
}
/*
* returns a pointer to the CertResponse with the given CertReqId
* (or the first one in case -1) inside a CertRepMessage
* returns NULL on error or if no suitable CertResponse available
*/
OSSL_CMP_CERTRESPONSE *
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
int rid)
{
OSSL_CMP_CERTRESPONSE *crep = NULL;
int i;
if (!ossl_assert(crm != NULL && crm->response != NULL))
return NULL;
for (i = 0; i < sk_OSSL_CMP_CERTRESPONSE_num(crm->response); i++) {
crep = sk_OSSL_CMP_CERTRESPONSE_value(crm->response, i);
if (suitable_rid(crep->certReqId, rid))
return crep;
}
CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND);
add_expected_rid(rid);
return NULL;
}
/*
* CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
* certificate from the given certResponse B<crep>.
* Uses the privkey in case of indirect POP from B<ctx>.
* Returns a pointer to a copy of the found certificate, or NULL if not found.
*/
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
const OSSL_CMP_CERTRESPONSE *crep)
{
OSSL_CMP_CERTORENCCERT *coec;
X509 *crt = NULL;
if (!ossl_assert(crep != NULL))
return NULL;
if (crep->certifiedKeyPair
&& (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) {
switch (coec->type) {
case OSSL_CMP_CERTORENCCERT_CERTIFICATE:
crt = X509_dup(coec->value.certificate);
break;
case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT:
/* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
if (privkey == NULL) {
CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
return NULL;
}
crt =
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert,
privkey);
break;
default:
CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE);
return NULL;
}
}
if (crt == NULL)
CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND);
return crt;
}
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file)
{
OSSL_CMP_MSG *msg = NULL;
BIO *bio = NULL;
if (!ossl_assert(file != NULL))
return NULL;
if ((bio = BIO_new_file(file, "rb")) == NULL)
return NULL;
msg = OSSL_d2i_CMP_MSG_bio(bio, NULL);
BIO_free(bio);
return msg;
}

313
crypto/cmp/cmp_protect.c Normal file
View File

@ -0,0 +1,313 @@
/*
* 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
*/
#include "cmp_local.h"
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h>
#include <openssl/x509.h>
/*
* This function is also used for verification from cmp_vfy.
*
* Calculate protection for given PKImessage utilizing the given credentials
* and the algorithm parameters set inside the message header's protectionAlg.
*
* Either secret or pkey must be set, the other must be NULL. Attempts doing
* PBMAC in case 'secret' is set and signature if 'pkey' is set - but will only
* do the protection already marked in msg->header->protectionAlg.
*
* returns ptr to ASN1_BIT_STRING containing protection on success, else NULL
*/
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
const ASN1_OCTET_STRING *secret,
EVP_PKEY *pkey)
{
ASN1_BIT_STRING *prot = NULL;
CMP_PROTECTEDPART prot_part;
const ASN1_OBJECT *algorOID = NULL;
int len;
size_t prot_part_der_len;
unsigned char *prot_part_der = NULL;
size_t sig_len;
unsigned char *protection = NULL;
const void *ppval = NULL;
int pptype = 0;
OSSL_CRMF_PBMPARAMETER *pbm = NULL;
ASN1_STRING *pbm_str = NULL;
const unsigned char *pbm_str_uc = NULL;
EVP_MD_CTX *evp_ctx = NULL;
int md_NID;
const EVP_MD *md = NULL;
if (!ossl_assert(msg != NULL))
return NULL;
/* construct data to be signed */
prot_part.header = msg->header;
prot_part.body = msg->body;
len = i2d_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
if (len < 0 || prot_part_der == NULL) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
goto end;
}
prot_part_der_len = (size_t) len;
if (msg->header->protectionAlg == NULL) {
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
goto end;
}
X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg);
if (secret != NULL && pkey == NULL) {
if (ppval == NULL) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
goto end;
}
if (NID_id_PasswordBasedMAC != OBJ_obj2nid(algorOID)) {
CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
goto end;
}
pbm_str = (ASN1_STRING *)ppval;
pbm_str_uc = pbm_str->data;
pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length);
if (pbm == NULL) {
CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
goto end;
}
if (!OSSL_CRMF_pbm_new(pbm, prot_part_der, prot_part_der_len,
secret->data, secret->length,
&protection, &sig_len))
goto end;
} else if (secret == NULL && pkey != NULL) {
/* TODO combine this with large parts of CRMF_poposigningkey_init() */
/* EVP_DigestSignInit() checks that pkey type is correct for the alg */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_NID, NULL)
|| (md = EVP_get_digestbynid(md_NID)) == NULL
|| (evp_ctx = EVP_MD_CTX_new()) == NULL) {
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
goto end;
}
if (EVP_DigestSignInit(evp_ctx, NULL, md, NULL, pkey) <= 0
|| EVP_DigestSignUpdate(evp_ctx, prot_part_der,
prot_part_der_len) <= 0
|| EVP_DigestSignFinal(evp_ctx, NULL, &sig_len) <= 0
|| (protection = OPENSSL_malloc(sig_len)) == NULL
|| EVP_DigestSignFinal(evp_ctx, protection, &sig_len) <= 0) {
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
goto end;
}
} else {
CMPerr(0, CMP_R_INVALID_ARGS);
goto end;
}
if ((prot = ASN1_BIT_STRING_new()) == NULL)
goto end;
/* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
prot->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) {
ASN1_BIT_STRING_free(prot);
prot = NULL;
}
end:
OSSL_CRMF_PBMPARAMETER_free(pbm);
EVP_MD_CTX_free(evp_ctx);
OPENSSL_free(protection);
OPENSSL_free(prot_part_der);
return prot;
}
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
{
if (!ossl_assert(ctx != NULL && msg != NULL))
return 0;
if (msg->extraCerts == NULL
&& (msg->extraCerts = sk_X509_new_null()) == NULL)
return 0;
if (ctx->clCert != NULL) {
/* Make sure that our own cert gets sent, in the first position */
if (!X509_up_ref(ctx->clCert))
return 0;
if (!sk_X509_push(msg->extraCerts, ctx->clCert)) {
X509_free(ctx->clCert);
return 0;
}
/* if we have untrusted store, try to add intermediate certs */
if (ctx->untrusted_certs != NULL) {
STACK_OF(X509) *chain =
ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->clCert);
int res = ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain,
1 /* no self-signed */,
1 /* no duplicates */, 0);
sk_X509_pop_free(chain, X509_free);
if (res == 0)
return 0;
}
}
/* add any additional certificates from ctx->extraCertsOut */
if (!ossl_cmp_sk_X509_add1_certs(msg->extraCerts, ctx->extraCertsOut, 0,
1 /* no duplicates */, 0))
return 0;
/* if none was found avoid empty ASN.1 sequence */
if (sk_X509_num(msg->extraCerts) == 0) {
sk_X509_free(msg->extraCerts);
msg->extraCerts = NULL;
}
return 1;
}
/*
* Create an X509_ALGOR structure for PasswordBasedMAC protection based on
* the pbm settings in the context
* returns pointer to X509_ALGOR on success, NULL on error
*/
static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx)
{
X509_ALGOR *alg = NULL;
OSSL_CRMF_PBMPARAMETER *pbm = NULL;
unsigned char *pbm_der = NULL;
int pbm_der_len;
ASN1_STRING *pbm_str = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
alg = X509_ALGOR_new();
pbm = OSSL_CRMF_pbmp_new(ctx->pbm_slen, ctx->pbm_owf, ctx->pbm_itercnt,
ctx->pbm_mac);
pbm_str = ASN1_STRING_new();
if (alg == NULL || pbm == NULL || pbm_str == NULL)
goto err;
if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0)
goto err;
if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len))
goto err;
OPENSSL_free(pbm_der);
X509_ALGOR_set0(alg, OBJ_nid2obj(NID_id_PasswordBasedMAC),
V_ASN1_SEQUENCE, pbm_str);
OSSL_CRMF_PBMPARAMETER_free(pbm);
return alg;
err:
ASN1_STRING_free(pbm_str);
X509_ALGOR_free(alg);
OPENSSL_free(pbm_der);
OSSL_CRMF_PBMPARAMETER_free(pbm);
return NULL;
}
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
{
if (!ossl_assert(ctx != NULL && msg != NULL))
return 0;
if (ctx->unprotectedSend)
return 1;
/* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */
if (ctx->secretValue != NULL) {
if ((msg->header->protectionAlg = create_pbmac_algor(ctx)) == NULL)
goto err;
if (ctx->referenceValue != NULL
&& !ossl_cmp_hdr_set1_senderKID(msg->header,
ctx->referenceValue))
goto err;
/*
* add any additional certificates from ctx->extraCertsOut
* while not needed to validate the signing cert, the option to do
* this might be handy for certain use cases
*/
if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
goto err;
if ((msg->protection =
ossl_cmp_calc_protection(msg, ctx->secretValue, NULL)) == NULL)
goto err;
} else {
/*
* use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and
* private key is given
*/
if (ctx->clCert != NULL && ctx->pkey != NULL) {
const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
int algNID = 0;
ASN1_OBJECT *alg = NULL;
/* make sure that key and certificate match */
if (!X509_check_private_key(ctx->clCert, ctx->pkey)) {
CMPerr(0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH);
goto err;
}
if (msg->header->protectionAlg == NULL)
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
goto err;
if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
EVP_PKEY_id(ctx->pkey))) {
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
goto err;
}
if ((alg = OBJ_nid2obj(algNID)) == NULL)
goto err;
if (!X509_ALGOR_set0(msg->header->protectionAlg,
alg, V_ASN1_UNDEF, NULL)) {
ASN1_OBJECT_free(alg);
goto err;
}
/*
* set senderKID to keyIdentifier of the used certificate according
* to section 5.1.1
*/
subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
if (subjKeyIDStr != NULL
&& !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
goto err;
/*
* Add ctx->clCert followed, if possible, by its chain built
* from ctx->untrusted_certs, and then ctx->extraCertsOut
*/
if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
goto err;
if ((msg->protection =
ossl_cmp_calc_protection(msg, NULL, ctx->pkey)) == NULL)
goto err;
} else {
CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
goto err;
}
}
return 1;
err:
CMPerr(0, CMP_R_ERROR_PROTECTING_MESSAGE);
return 0;
}

View File

@ -56,7 +56,7 @@ const char *ossl_cmp_PKIStatus_to_string(int status)
return "PKIStatus: revocation notification - a revocation of the cert has occurred";
case OSSL_CMP_PKISTATUS_keyUpdateWarning:
return "PKIStatus: key update warning - update already done for the cert";
default:
default:
{
char buf[40];
BIO_snprintf(buf, sizeof(buf), "PKIStatus: invalid=%d", status);
@ -299,4 +299,3 @@ OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
ASN1_UTF8STRING_free(utf8_text);
return NULL;
}

View File

@ -235,6 +235,5 @@ IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSG)
ASN1_ITEM_TEMPLATE(OSSL_CRMF_MSGS) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
OSSL_CRMF_MSGS, OSSL_CRMF_MSG)
ASN1_ITEM_TEMPLATE_END(OSSL_CRMF_MSGS)
ASN1_ITEM_TEMPLATE_END(OSSL_CRMF_MSGS)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSGS)

View File

@ -97,10 +97,10 @@ static int OSSL_CRMF_MSG_push0_regCtrl(OSSL_CRMF_MSG *crm,
return 0;
}
/* id-regCtrl-regToken Control (section 6.1) */
/* id-regCtrl-regToken Control (section 6.1) */
IMPLEMENT_CRMF_CTRL_FUNC(regToken, ASN1_STRING, regCtrl)
/* id-regCtrl-authenticator Control (section 6.2) */
/* id-regCtrl-authenticator Control (section 6.2) */
#define ASN1_UTF8STRING_dup ASN1_STRING_dup
IMPLEMENT_CRMF_CTRL_FUNC(authenticator, ASN1_UTF8STRING, regCtrl)
@ -153,11 +153,11 @@ int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(
return ASN1_INTEGER_set(pi->action, action);
}
/* id-regCtrl-pkiPublicationInfo Control (section 6.3) */
/* id-regCtrl-pkiPublicationInfo Control (section 6.3) */
IMPLEMENT_CRMF_CTRL_FUNC(pkiPublicationInfo, OSSL_CRMF_PKIPUBLICATIONINFO,
regCtrl)
/* id-regCtrl-oldCertID Control (section 6.5) from the given */
/* id-regCtrl-oldCertID Control (section 6.5) from the given */
IMPLEMENT_CRMF_CTRL_FUNC(oldCertID, OSSL_CRMF_CERTID, regCtrl)
OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer,
@ -188,10 +188,9 @@ OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer,
return NULL;
}
/*
* id-regCtrl-protocolEncrKey Control (section 6.6)
*
*/
/*
* id-regCtrl-protocolEncrKey Control (section 6.6)
*/
IMPLEMENT_CRMF_CTRL_FUNC(protocolEncrKey, X509_PUBKEY, regCtrl)
/*-
@ -567,7 +566,7 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
* return 1 if the type of req->popo->value.keyEncipherment
* is OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE and
* its value.subsequentMessage == OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT
*/
*/
case OSSL_CRMF_POPO_KEYAGREE:
default:
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
@ -702,7 +701,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
if ((iv = OPENSSL_malloc(EVP_CIPHER_iv_length(cipher))) == NULL)
goto end;
if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv,
EVP_CIPHER_iv_length(cipher))
EVP_CIPHER_iv_length(cipher))
!= EVP_CIPHER_iv_length(cipher)) {
CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
CRMF_R_MALFORMED_IV);

View File

@ -217,7 +217,7 @@ struct ossl_crmf_pbmparameter_st {
ASN1_INTEGER *iterationCount;
X509_ALGOR *mac;
} /* OSSL_CRMF_PBMPARAMETER */;
#define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */
# define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */
/*-
* POPOSigningKeyInput ::= SEQUENCE {
@ -232,7 +232,7 @@ struct ossl_crmf_pbmparameter_st {
* -- on the DER-encoded value of publicKey
* publicKey SubjectPublicKeyInfo -- from CertTemplate
* }
*/
*/
typedef struct ossl_crmf_poposigningkeyinput_authinfo_st {
int type;
union {

View File

@ -133,8 +133,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
int ok = 0;
EVP_MAC *mac = NULL;
EVP_MAC_CTX *mctx = NULL;
OSSL_PARAM macparams[3] =
{ OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
OSSL_PARAM macparams[3] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END};
if (out == NULL || pbmp == NULL || pbmp->mac == NULL
|| pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) {
@ -193,16 +192,15 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
mac_nid = OBJ_obj2nid(pbmp->mac->algorithm);
if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL)
|| ((mdname = OBJ_nid2sn(hmac_md_nid)) == NULL)) {
|| (mdname = OBJ_nid2sn(hmac_md_nid)) == NULL) {
CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM);
goto err;
}
macparams[0] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
(char *)mdname, 0);
macparams[1] =
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, basekey, bklen);
macparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
(char *)mdname, 0);
macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
basekey, bklen);
if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
|| (mctx = EVP_MAC_CTX_new(mac)) == NULL
|| !EVP_MAC_CTX_set_params(mctx, macparams)

View File

@ -2066,13 +2066,43 @@ BN_R_PRIVATE_KEY_TOO_LARGE:117:private key too large
BN_R_P_IS_NOT_PRIME:112:p is not prime
BN_R_TOO_MANY_ITERATIONS:113:too many iterations
BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables
CMP_R_BAD_REQUEST_ID:108:bad request id
CMP_R_CERTID_NOT_FOUND:109:certid not found
CMP_R_CERTIFICATE_NOT_FOUND:112:certificate 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_CERTCONF:116:error creating certconf
CMP_R_ERROR_CREATING_CERTREP:117:error creating certrep
CMP_R_ERROR_CREATING_ERROR:118:error creating error
CMP_R_ERROR_CREATING_GENM:119:error creating genm
CMP_R_ERROR_CREATING_GENP:120:error creating genp
CMP_R_ERROR_CREATING_P10CR:121:error creating p10cr
CMP_R_ERROR_CREATING_PKICONF:122:error creating pkiconf
CMP_R_ERROR_CREATING_POLLREP:123:error creating pollrep
CMP_R_ERROR_CREATING_POLLREQ:124:error creating pollreq
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_PROTECTING_MESSAGE:127:error protecting message
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range
CMP_R_INVALID_ARGS:100:invalid args
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\
missing key input for creating protection
CMP_R_MISSING_PRIVATE_KEY:131:missing private key
CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
CMP_R_NO_STDIO:194:no stdio
CMP_R_NULL_ARGUMENT:103:null argument
CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found
CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid
CMS_R_ADD_SIGNER_ERROR:99:add signer error
CMS_R_ATTRIBUTE_ERROR:161:attribute error
CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present

View File

@ -0,0 +1,40 @@
=pod
=head1 NAME
OSSL_CMP_MSG_get0_header
- function(s) manipulating CMP messages
=head1 SYNOPSIS
#include <openssl/cmp.h>
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
=head1 DESCRIPTION
OSSL_CMP_MSG_get0_header returns the header of the given CMP message.
=head1 NOTES
CMP is defined in RFC 4210.
=head1 RETURN VALUES
CMP_MSG_get0_header() returns the intended pointer value as described above
or NULL if the respective entry does not exist and 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

View File

@ -264,7 +264,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val);
int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt);
/* CMP-specific callback for logging and outputting the error queue: */
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_log_cb_t cb);
#define OSSL_CMP_CTX_set_log_verbosity(ctx, level) \
# define OSSL_CMP_CTX_set_log_verbosity(ctx, level) \
OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_LOG_VERBOSITY, level)
void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx);
/* message transfer: */
@ -346,8 +346,12 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
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);
# ifdef __cplusplus
/* 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);
# ifdef __cplusplus
}
# endif
# endif
# endif /* !defined OPENSSL_NO_CMP */
#endif /* !defined OPENSSL_CMP_H */

View File

@ -26,13 +26,12 @@ extern "C" {
/*
* convenience functions for CMP-specific logging via the trace API
*/
int OSSL_CMP_log_open(void);
void OSSL_CMP_log_close(void);
# define OSSL_CMP_LOG_PREFIX "CMP "
/* in OSSL_CMP_LOG_START, cannot use OPENSSL_FUNC when expands to __func__ */
# define OSSL_CMP_LOG_START "%s:" OPENSSL_FILE ":" \
OPENSSL_MSTR(OPENSSL_LINE) ":" OSSL_CMP_LOG_PREFIX
OPENSSL_MSTR(OPENSSL_LINE) ":" OSSL_CMP_LOG_PREFIX
# define OSSL_CMP_alert(msg) OSSL_CMP_log(ALERT, msg)
# define OSSL_CMP_err(msg) OSSL_CMP_log(ERROR, msg)
# define OSSL_CMP_warn(msg) OSSL_CMP_log(WARN, msg)
@ -72,8 +71,8 @@ typedef int (*OSSL_cmp_log_cb_t)(const char *func, const char *file, int line,
/* use of the logging callback for outputting error queue */
void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn);
# ifdef __cplusplus
# ifdef __cplusplus
}
# endif
# endif
# endif /* !defined OPENSSL_NO_CMP */
#endif /* !defined OPENSSL_CMP_UTIL_H */

View File

@ -33,13 +33,42 @@ int ERR_load_CMP_strings(void);
/*
* CMP reason codes.
*/
# define CMP_R_BAD_REQUEST_ID 108
# define CMP_R_CERTID_NOT_FOUND 109
# define CMP_R_CERTIFICATE_NOT_FOUND 112
# 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_CERTCONF 116
# define CMP_R_ERROR_CREATING_CERTREP 117
# define CMP_R_ERROR_CREATING_ERROR 118
# define CMP_R_ERROR_CREATING_GENM 119
# define CMP_R_ERROR_CREATING_GENP 120
# define CMP_R_ERROR_CREATING_P10CR 121
# define CMP_R_ERROR_CREATING_PKICONF 122
# define CMP_R_ERROR_CREATING_POLLREP 123
# define CMP_R_ERROR_CREATING_POLLREQ 124
# 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_PROTECTING_MESSAGE 127
# define CMP_R_ERROR_SETTING_CERTHASH 128
# define CMP_R_FAILURE_OBTAINING_RANDOM 110
# define CMP_R_FAIL_INFO_OUT_OF_RANGE 129
# define CMP_R_INVALID_ARGS 100
# define CMP_R_MULTIPLE_SAN_SOURCES 102
# define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130
# define CMP_R_MISSING_PRIVATE_KEY 131
# define CMP_R_MISSING_SENDER_IDENTIFICATION 111
# define CMP_R_MULTIPLE_SAN_SOURCES 102
# define CMP_R_NO_STDIO 194
# define CMP_R_NULL_ARGUMENT 103
# define CMP_R_PKISTATUSINFO_NOT_FOUND 132
# define CMP_R_UNEXPECTED_PKIBODY 133
# define CMP_R_UNKNOWN_ALGORITHM_ID 134
# define CMP_R_UNKNOWN_CERT_TYPE 135
# define CMP_R_UNSUPPORTED_ALGORITHM 136
# define CMP_R_UNSUPPORTED_KEY_TYPE 137
# define CMP_R_WRONG_ALGORITHM_OID 138
# endif
#endif

View File

@ -481,7 +481,8 @@ IF[{- !$disabled{tests} -}]
DEPEND[conf_include_test]=../libcrypto libtestutil.a
IF[{- !$disabled{cmp} -}]
PROGRAMS{noinst}=cmp_asn_test cmp_ctx_test cmp_status_test cmp_hdr_test
PROGRAMS{noinst}=cmp_asn_test cmp_ctx_test cmp_status_test cmp_hdr_test \
cmp_protect_test cmp_msg_test
ENDIF
SOURCE[cmp_asn_test]=cmp_asn_test.c cmp_testlib.c
@ -500,6 +501,14 @@ IF[{- !$disabled{tests} -}]
INCLUDE[cmp_status_test]=.. ../include ../apps/include
DEPEND[cmp_status_test]=../libcrypto.a libtestutil.a
SOURCE[cmp_protect_test]=cmp_status_test.c cmp_testlib.c
INCLUDE[cmp_protect_test]=.. ../include ../apps/include
DEPEND[cmp_protect_test]=../libcrypto.a libtestutil.a
SOURCE[cmp_msg_test]=cmp_status_test.c cmp_testlib.c
INCLUDE[cmp_msg_test]=.. ../include ../apps/include
DEPEND[cmp_msg_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

View File

@ -40,8 +40,7 @@ static void tear_down(CMP_ASN_TEST_FIXTURE *fixture)
OPENSSL_free(fixture);
}
static int execute_cmp_asn1_get_int_test(CMP_ASN_TEST_FIXTURE *
fixture)
static int execute_cmp_asn1_get_int_test(CMP_ASN_TEST_FIXTURE *fixture)
{
ASN1_INTEGER *asn1integer = ASN1_INTEGER_new();
ASN1_INTEGER_set(asn1integer, 77);
@ -115,8 +114,10 @@ int setup_tests(void)
ADD_TEST(test_cmp_asn1_get_int);
ADD_TEST(test_ASN1_OCTET_STRING_set);
ADD_TEST(test_ASN1_OCTET_STRING_set_tgt_is_src);
/* TODO make sure that total number of tests (here currently 24) is shown,
also for other cmp_*text.c. Currently the test drivers always show 1. */
/*
* TODO make sure that total number of tests (here currently 24) is shown,
* also for other cmp_*text.c. Currently the test drivers always show 1.
*/
return 1;
}

View File

@ -39,7 +39,8 @@ static OSSL_CMP_CTX_TEST_FIXTURE *set_up(const char *const test_case_name)
return fixture;
}
static STACK_OF(X509) *sk_X509_new_1(void) {
static STACK_OF(X509) *sk_X509_new_1(void)
{
STACK_OF(X509) *sk = sk_X509_new_null();
X509 *x = X509_new();
@ -51,7 +52,8 @@ static STACK_OF(X509) *sk_X509_new_1(void) {
return sk;
}
static void sk_X509_pop_X509_free(STACK_OF(X509) *sk) {
static void sk_X509_pop_X509_free(STACK_OF(X509) *sk)
{
sk_X509_pop_free(sk, X509_free);
}
@ -75,7 +77,6 @@ static int execute_CTX_reinit_test(OSSL_CMP_CTX_TEST_FIXTURE *fixture)
|| !OSSL_CMP_CTX_set1_transactionID(ctx, bytes)
|| !OSSL_CMP_CTX_set1_senderNonce(ctx, bytes)
|| !ossl_cmp_ctx_set1_recipNonce(ctx, bytes))
goto err;
if (!TEST_true(OSSL_CMP_CTX_reinit(ctx)))
@ -335,7 +336,7 @@ static int execute_CTX_##SETN##_##GETN##_##FIELD( \
CMP_CTX *ctx = fixture->ctx; \
int (*set_fn)(CMP_CTX *ctx, TYPE) = \
(int (*)(CMP_CTX *ctx, TYPE))PREFIX##_##SETN##_##FIELD; \
/* need type cast in above assignment because TYPE arg sometimes is const */ \
/* need type cast in above assignment because TYPE arg sometimes is const */ \
TYPE (*get_fn)(const CMP_CTX *ctx) = OSSL_CMP_CTX_##GETN##_##FIELD; \
TYPE val1_to_free = NEW; \
TYPE val1 = val1_to_free; \
@ -467,17 +468,20 @@ static int test_CTX_##SETN##_##GETN##_##FIELD(void) \
return result; \
}
static char *char_new(void) {
static char *char_new(void)
{
return OPENSSL_strdup("test");
}
static void char_free(char *val) {
static void char_free(char *val)
{
OPENSSL_free(val);
}
#define EMPTY_SK_X509(x) ((x) == NULL || sk_X509_num(x) == 0)
static X509_STORE *X509_STORE_new_1(void) {
static X509_STORE *X509_STORE_new_1(void)
{
X509_STORE *store = X509_STORE_new();
if (store != NULL)
@ -497,24 +501,24 @@ static X509_STORE *X509_STORE_new_1(void) {
#define DEFINE_SET_GET_TEST(OSSL_CMP, CTX, N, M, DUP, FIELD, TYPE) \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP##_##CTX, set##N, get##M, DUP, FIELD, \
TYPE*, NULL, IS_0, TYPE##_new(), TYPE##_free)
TYPE*, NULL, IS_0, TYPE##_new(), TYPE##_free)
#define DEFINE_SET_GET_SK_TEST_DEFAULT(OSSL_CMP, CTX, N, M, FIELD, ELEM_TYPE, \
DEFAULT, NEW, FREE) \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP##_##CTX, set##N, get##M, 1, FIELD, \
STACK_OF(ELEM_TYPE)*, NULL, DEFAULT, NEW, FREE)
STACK_OF(ELEM_TYPE)*, NULL, DEFAULT, NEW, FREE)
#define DEFINE_SET_GET_SK_TEST(OSSL_CMP, CTX, N, M, FIELD, T) \
DEFINE_SET_GET_SK_TEST_DEFAULT(OSSL_CMP, CTX, N, M, FIELD, T, \
IS_0, sk_##T##_new_null(), sk_##T##_free)
IS_0, sk_##T##_new_null(), sk_##T##_free)
#define DEFINE_SET_GET_SK_X509_TEST(OSSL_CMP, CTX, N, M, FNAME) \
DEFINE_SET_GET_SK_TEST_DEFAULT(OSSL_CMP, CTX, N, M, FNAME, X509, \
EMPTY_SK_X509, \
sk_X509_new_1(), sk_X509_pop_X509_free)
EMPTY_SK_X509, \
sk_X509_new_1(), sk_X509_pop_X509_free)
#define DEFINE_SET_GET_TEST_DEFAULT(OSSL_CMP, CTX, N, M, DUP, FIELD, TYPE, \
DEFAULT) \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP##_##CTX, set##N, get##M, DUP, FIELD, \
TYPE*, NULL, DEFAULT, TYPE##_new(), TYPE##_free)
TYPE*, NULL, DEFAULT, TYPE##_new(), TYPE##_free)
#define DEFINE_SET_TEST_DEFAULT(OSSL_CMP, CTX, N, DUP, FIELD, TYPE, DEFAULT) \
static TYPE *OSSL_CMP_CTX_get0_##FIELD(const CMP_CTX *ctx) \
{ \
@ -530,27 +534,26 @@ static X509_STORE *X509_STORE_new_1(void) {
return ctx == NULL ? ERR(NULL) : ctx->FIELD; \
} \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP##_##CTX, set##N, get0, 1, FIELD, \
STACK_OF(TYPE)*, NULL, IS_0, \
sk_##TYPE##_new_null(), sk_##TYPE##_free)
STACK_OF(TYPE)*, NULL, IS_0, \
sk_##TYPE##_new_null(), sk_##TYPE##_free)
#define DEFINE_SET_CB_TEST(FIELD) \
static OSSL_cmp_##FIELD##_t \
OSSL_CMP_CTX_get_##FIELD(const CMP_CTX *ctx) \
static OSSL_cmp_##FIELD##_t OSSL_CMP_CTX_get_##FIELD(const CMP_CTX *ctx) \
{ \
if (ctx == NULL) \
CMPerr(0, CMP_R_NULL_ARGUMENT); \
return ctx == NULL ? NULL /* cannot use ERR(NULL) here */ : ctx->FIELD;\
} \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set, get, 0, FIELD, \
OSSL_cmp_##FIELD##_t, NULL, IS_0, \
test_##FIELD, DROP)
OSSL_cmp_##FIELD##_t, NULL, IS_0, \
test_##FIELD, DROP)
#define DEFINE_SET_GET_P_VOID_TEST(FIELD) \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set, get, 0, FIELD, void*, \
NULL, IS_0, ((void *)1), DROP)
NULL, IS_0, ((void *)1), DROP)
#define DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, DEFAULT) \
DEFINE_SET_GET_BASE_TEST(OSSL_CMP##_##CTX, set, get, 0, FIELD, int, -1, \
DEFAULT, 1, DROP)
DEFAULT, 1, DROP)
#define DEFINE_SET_GET_INT_TEST(OSSL_CMP, CTX, FIELD) \
DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_NEG)
#define DEFINE_SET_PORT_TEST(FIELD) \
@ -590,8 +593,9 @@ static X509_STORE *X509_STORE_new_1(void) {
#define push0 0
#define push1 1
#define DEFINE_PUSH_BASE_TEST(PUSHN, DUP, FIELD, ELEM, TYPE, T, \
DEFAULT, NEW, FREE) \
static TYPE sk_top_##FIELD(const CMP_CTX *ctx) { \
DEFAULT, NEW, FREE) \
static TYPE sk_top_##FIELD(const CMP_CTX *ctx) \
{ \
return sk_##T##_value(ctx->FIELD, sk_##T##_num(ctx->FIELD) - 1); \
} \
\
@ -600,7 +604,9 @@ static int execute_CTX_##PUSHN##_##ELEM(OSSL_CMP_CTX_TEST_FIXTURE *fixture) \
CMP_CTX *ctx = fixture->ctx; \
int (*push_fn)(CMP_CTX *ctx, TYPE) = \
(int (*)(CMP_CTX *ctx, TYPE))OSSL_CMP_CTX_##PUSHN##_##ELEM; \
/* need type cast in above assignment because TYPE arg sometimes is const */ \
/* \
* need type cast in above assignment because TYPE arg sometimes is const \
*/ \
int n_elem = sk_##T##_num(ctx->FIELD); \
STACK_OF(TYPE) field_read; \
TYPE val1_to_free = NEW; \
@ -696,7 +702,7 @@ static int test_CTX_##PUSHN##_##ELEM(void) \
#define DEFINE_PUSH_TEST(N, DUP, FIELD, ELEM, TYPE) \
DEFINE_PUSH_BASE_TEST(push##N, DUP, FIELD, ELEM, TYPE*, TYPE, \
IS_0, TYPE##_new(), TYPE##_free)
IS_0, TYPE##_new(), TYPE##_free)
void cleanup_tests(void)
{
@ -704,9 +710,9 @@ void cleanup_tests(void)
}
DEFINE_SET_GET_ARG_FN(set, get, option, 16, int)
/* option == OSSL_CMP_OPT_IGNORE_KEYUSAGE */
/* option == OSSL_CMP_OPT_IGNORE_KEYUSAGE */
DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set, get, 0, option_16, int, -1, IS_0, \
1 /* true */, DROP)
1 /* true */, DROP)
#ifndef OPENSSL_NO_TRACE
DEFINE_SET_CB_TEST(log_cb)
@ -726,8 +732,8 @@ DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 0, srvCert, X509)
DEFINE_SET_TEST(ossl_cmp, ctx, 0, 0, validatedSrvCert, X509)
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, expected_sender, X509_NAME)
DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set0, get0, 0, trustedStore,
X509_STORE*, NULL,
DEFAULT_STORE, X509_STORE_new_1(), X509_STORE_free)
X509_STORE*, NULL,
DEFAULT_STORE, X509_STORE_new_1(), X509_STORE_free)
DEFINE_SET_GET_SK_X509_TEST(OSSL_CMP, CTX, 1, 0, untrusted_certs)
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 0, clCert, X509)
@ -741,11 +747,10 @@ DEFINE_SET_GET_TEST(OSSL_CMP, CTX, 0, 0, 0, newPkey_1, EVP_PKEY)
DEFINE_SET_GET_ARG_FN(set0, get0, newPkey, 0, EVP_PKEY*) /* priv == 0 */
DEFINE_SET_GET_TEST(OSSL_CMP, CTX, 0, 0, 0, newPkey_0, EVP_PKEY)
DEFINE_SET_GET1_STR_FN(set1, referenceValue)
DEFINE_SET_GET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, 1, referenceValue_str,
char, IS_0)
DEFINE_SET_GET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, 1, referenceValue_str, char,
IS_0)
DEFINE_SET_GET1_STR_FN(set1, secretValue)
DEFINE_SET_GET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, 1, secretValue_str,
char, IS_0)
DEFINE_SET_GET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, 1, secretValue_str, char, IS_0)
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, issuer, X509_NAME)
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, subjectName, X509_NAME)
#ifdef ISSUE_9504_RESOLVED
@ -768,8 +773,8 @@ DEFINE_SET_GET_TEST(ossl_cmp, ctx, 0, 0, 0, newCert, X509)
DEFINE_SET_GET_SK_X509_TEST(ossl_cmp, ctx, 1, 1, caPubs)
DEFINE_SET_GET_SK_X509_TEST(ossl_cmp, ctx, 1, 1, extraCertsIn)
DEFINE_SET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, transactionID,
ASN1_OCTET_STRING, IS_0)
DEFINE_SET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, transactionID, ASN1_OCTET_STRING,
IS_0)
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, senderNonce, ASN1_OCTET_STRING)
DEFINE_SET_TEST(ossl_cmp, ctx, 1, 1, recipNonce, ASN1_OCTET_STRING)
@ -779,9 +784,9 @@ int setup_tests(void)
/* OSSL_CMP_CTX_free() is tested by tear_down() */
ADD_TEST(test_CTX_reinit);
/* various CMP options: */
/* various CMP options: */
ADD_TEST(test_CTX_set_get_option_16);
/* CMP-specific callback for logging and outputting the error queue: */
/* CMP-specific callback for logging and outputting the error queue: */
#ifndef OPENSSL_NO_TRACE
ADD_TEST(test_CTX_set_get_log_cb);
#endif
@ -793,13 +798,14 @@ int setup_tests(void)
*/
ADD_TEST(test_cmp_ctx_log_cb);
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
/* also tests OSSL_CMP_CTX_set_log_cb(), OSSL_CMP_print_errors_cb(),
ossl_cmp_add_error_txt(), and the macros
ossl_cmp_add_error_data and ossl_cmp_add_error_line:
*/
/*
* also tests OSSL_CMP_CTX_set_log_cb(), OSSL_CMP_print_errors_cb(),
* ossl_cmp_add_error_txt(), and the macros
* ossl_cmp_add_error_data and ossl_cmp_add_error_line:
*/
ADD_TEST(test_CTX_print_errors);
#endif
/* message transfer: */
/* message transfer: */
ADD_TEST(test_CTX_set1_get0_serverPath);
ADD_TEST(test_CTX_set1_get0_serverName);
ADD_TEST(test_CTX_set_get_serverPort);
@ -809,29 +815,31 @@ int setup_tests(void)
ADD_TEST(test_CTX_set_get_http_cb_arg);
ADD_TEST(test_CTX_set_get_transfer_cb);
ADD_TEST(test_CTX_set_get_transfer_cb_arg);
/* server authentication: */
/* server authentication: */
ADD_TEST(test_CTX_set1_get0_srvCert);
ADD_TEST(test_CTX_set0_get0_validatedSrvCert);
ADD_TEST(test_CTX_set1_get0_expected_sender);
ADD_TEST(test_CTX_set0_get0_trustedStore);
ADD_TEST(test_CTX_set1_get0_untrusted_certs);
/* client authentication: */
/* client authentication: */
ADD_TEST(test_CTX_set1_get0_clCert);
ADD_TEST(test_CTX_set1_get0_pkey);
/* the following two also test ossl_cmp_asn1_octet_string_set1_bytes(): */
ADD_TEST(test_CTX_set1_get1_referenceValue_str);
ADD_TEST(test_CTX_set1_get1_secretValue_str);
/* CMP message header and extra certificates: */
/* CMP message header and extra certificates: */
ADD_TEST(test_CTX_set1_get0_recipient);
ADD_TEST(test_CTX_push0_geninfo_ITAV);
ADD_TEST(test_CTX_set1_get0_extraCertsOut);
/* certificate template: */
/* certificate template: */
ADD_TEST(test_CTX_set0_get0_newPkey_1);
ADD_TEST(test_CTX_set0_get0_newPkey_0);
ADD_TEST(test_CTX_set1_get0_issuer);
ADD_TEST(test_CTX_set1_get0_subjectName);
#ifdef ISSUE_9504_RESOLVED
/* test currently fails, see https://github.com/openssl/openssl/issues/9504 */
/*
* test currently fails, see https://github.com/openssl/openssl/issues/9504
*/
ADD_TEST(test_CTX_push1_subjectAltName);
#endif
ADD_TEST(test_CTX_set0_get0_reqExtensions);
@ -839,28 +847,28 @@ int setup_tests(void)
ADD_TEST(test_CTX_push0_policy);
ADD_TEST(test_CTX_set1_get0_oldCert);
#ifdef ISSUE_9504_RESOLVED
/* test currently fails, see https://github.com/openssl/openssl/issues/9504 */
/*
* test currently fails, see https://github.com/openssl/openssl/issues/9504
*/
ADD_TEST(test_CTX_set1_get0_p10CSR);
#endif
/* misc body contents: */
/* misc body contents: */
ADD_TEST(test_CTX_push0_genm_ITAV);
/* certificate confirmation: */
/* certificate confirmation: */
ADD_TEST(test_CTX_set_get_certConf_cb);
ADD_TEST(test_CTX_set_get_certConf_cb_arg);
/* result fetching: */
/* result fetching: */
ADD_TEST(test_CTX_set_get_status);
ADD_TEST(test_CTX_set0_get0_statusString);
ADD_TEST(test_CTX_set_get_failInfoCode);
ADD_TEST(test_CTX_set0_get0_newCert);
ADD_TEST(test_CTX_set1_get1_caPubs);
ADD_TEST(test_CTX_set1_get1_extraCertsIn);
/* exported for testing and debugging purposes: */
/* exported for testing and debugging purposes: */
/* the following three also test ossl_cmp_asn1_octet_string_set1(): */
ADD_TEST(test_CTX_set1_get0_transactionID);
ADD_TEST(test_CTX_set1_get0_senderNonce);
ADD_TEST(test_CTX_set1_get0_recipNonce);
/* TODO ossl_cmp_build_cert_chain() will be tested with cmp_protect.c*/
/* ossl_cmp_build_cert_chain() is tested in cmp_protect.c */
return 1;
}

View File

@ -193,7 +193,9 @@ static int execute_HDR_set1_senderKID_test(CMP_HDR_TEST_FIXTURE *fixture)
if (!TEST_ptr(senderKID))
return 0;
ASN1_OCTET_STRING_set(senderKID, rand_data, sizeof(rand_data));
if (!TEST_int_eq(ASN1_OCTET_STRING_set(senderKID, rand_data,
sizeof(rand_data)), 1))
return 0;
if (!TEST_int_eq(ossl_cmp_hdr_set1_senderKID(fixture->hdr, senderKID), 1))
return 0;
if (!TEST_int_eq(
@ -372,7 +374,7 @@ static int execute_HDR_init_test(CMP_HDR_TEST_FIXTURE *fixture)
|| !TEST_true(0 == ASN1_OCTET_STRING_cmp(
ossl_cmp_hdr_get0_senderNonce(fixture->hdr),
fixture->cmp_ctx->senderNonce))
|| !TEST_true(0 == ASN1_OCTET_STRING_cmp(
|| !TEST_true(0 == ASN1_OCTET_STRING_cmp(
OSSL_CMP_HDR_get0_transactionID(fixture->hdr),
fixture->cmp_ctx->transactionID)))
goto err;
@ -414,9 +416,9 @@ static int test_HDR_init_with_subject(void)
fixture->expected = 1;
if (!TEST_ptr(subject = X509_NAME_new())
|| !TEST_true(X509_NAME_ADD(subject, "CN", "Common Name"))
|| !TEST_true(OSSL_CMP_CTX_set1_subjectName(fixture->cmp_ctx,
subject))) {
|| !TEST_true(X509_NAME_ADD(subject, "CN", "Common Name"))
|| !TEST_true(OSSL_CMP_CTX_set1_subjectName(fixture->cmp_ctx,
subject))) {
tear_down(fixture);
fixture = NULL;
}
@ -461,8 +463,10 @@ int setup_tests(void)
ADD_TEST(test_HDR_init);
ADD_TEST(test_HDR_init_with_subject);
ADD_TEST(test_HDR_init_no_ref_no_subject);
/* TODO make sure that total number of tests (here currently 24) is shown,
also for other cmp_*text.c. Currently the test drivers always show 1. */
/*
* TODO make sure that total number of tests (here currently 24) is shown,
* also for other cmp_*text.c. Currently the test drivers always show 1.
*/
return 1;
}

577
test/cmp_msg_test.c Normal file
View File

@ -0,0 +1,577 @@
/*
* 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
*/
#include "cmp_testlib.h"
static const char *server_cert_f;
static const char *pkcs10_f;
typedef struct test_fixture {
const char *test_case_name;
OSSL_CMP_CTX *cmp_ctx;
/* for msg create tests */
int bodytype;
int err_code;
/* for certConf */
int fail_info;
/* for protection tests */
OSSL_CMP_MSG *msg;
int expected;
/* for error and response messages */
OSSL_CMP_PKISI *si;
} CMP_MSG_TEST_FIXTURE;
static unsigned char ref[CMP_TEST_REFVALUE_LENGTH];
static void tear_down(CMP_MSG_TEST_FIXTURE *fixture)
{
OSSL_CMP_CTX_free(fixture->cmp_ctx);
OSSL_CMP_MSG_free(fixture->msg);
OSSL_CMP_PKISI_free(fixture->si);
OPENSSL_free(fixture);
}
#define SET_OPT_UNPROTECTED_SEND(ctx, val) \
OSSL_CMP_CTX_set_option((ctx), OSSL_CMP_OPT_UNPROTECTED_SEND, (val))
static CMP_MSG_TEST_FIXTURE *set_up(const char *const test_case_name)
{
CMP_MSG_TEST_FIXTURE *fixture;
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
return NULL;
fixture->test_case_name = test_case_name;
if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new())
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 1))
|| !TEST_true(OSSL_CMP_CTX_set1_referenceValue(fixture->cmp_ctx,
ref, sizeof(ref)))) {
tear_down(fixture);
return NULL;
}
return fixture;
}
static EVP_PKEY *newkey = NULL;
static X509 *cert = NULL;
#define EXECUTE_MSG_CREATION_TEST(expr) \
do { \
OSSL_CMP_MSG *msg = NULL; \
int good = fixture->expected != 0 ? \
TEST_ptr(msg = (expr)) && TEST_true(valid_asn1_encoding(msg)) : \
TEST_ptr_null(msg = (expr)); \
\
OSSL_CMP_MSG_free(msg); \
return good; \
} while (0)
/*-
* The following tests call a cmp message creation function.
* if fixture->expected != 0:
* returns 1 if the message is created and syntactically correct.
* if fixture->expected == 0
* returns 1 if message creation returns NULL
*/
static int execute_certreq_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_certReq_new(fixture->cmp_ctx,
fixture->bodytype,
fixture->err_code));
}
static int execute_errormsg_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_error_new(fixture->cmp_ctx, fixture->si,
fixture->err_code,
NULL /* fixture->free_text */,
0));
}
static int execute_rr_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_rr_new(fixture->cmp_ctx));
}
static int execute_certconf_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_certConf_new
(fixture->cmp_ctx, fixture->fail_info, NULL));
}
static int execute_genm_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_genm_new(fixture->cmp_ctx));
}
static int execute_pollreq_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_pollReq_new(fixture->cmp_ctx, 4711));
}
static int execute_pkimessage_create_test(CMP_MSG_TEST_FIXTURE *fixture)
{
EXECUTE_MSG_CREATION_TEST(ossl_cmp_msg_create
(fixture->cmp_ctx, fixture->bodytype));
}
static int set1_newPkey(OSSL_CMP_CTX *ctx, EVP_PKEY* pkey)
{
if (!EVP_PKEY_up_ref(pkey))
return 0;
if (!OSSL_CMP_CTX_set0_newPkey(ctx, 1, pkey)) {
EVP_PKEY_free(pkey);
return 0;
}
return 1;
}
static int test_cmp_create_ir_protection_set(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
unsigned char secret[16];
fixture->bodytype = OSSL_CMP_PKIBODY_IR;
fixture->err_code = CMP_R_ERROR_CREATING_IR;
fixture->expected = 1;
if (!TEST_int_eq(1, RAND_bytes(secret, sizeof(secret)))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(ctx, 0))
|| !TEST_true(set1_newPkey(ctx, newkey))
|| !TEST_true(OSSL_CMP_CTX_set1_secretValue(ctx, secret,
sizeof(secret)))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_ir_protection_fails(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_IR;
fixture->err_code = CMP_R_ERROR_CREATING_IR;
fixture->expected = 0;
if (!TEST_true(OSSL_CMP_CTX_set1_pkey(fixture->cmp_ctx, newkey))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 0))
|| !TEST_true(OSSL_CMP_CTX_set1_clCert(fixture->cmp_ctx, cert))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_cr_without_key(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_CR;
fixture->err_code = CMP_R_ERROR_CREATING_CR;
fixture->expected = 0;
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_cr(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_CR;
fixture->err_code = CMP_R_ERROR_CREATING_CR;
fixture->expected = 1;
if (!TEST_true(set1_newPkey(fixture->cmp_ctx, newkey))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_certreq_with_invalid_bodytype(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_RR;
fixture->err_code = CMP_R_ERROR_CREATING_IR;
fixture->expected = 0;
if (!TEST_true(set1_newPkey(fixture->cmp_ctx, newkey))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_p10cr(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
X509_REQ *p10cr = NULL;
fixture->bodytype = OSSL_CMP_PKIBODY_P10CR;
fixture->err_code = CMP_R_ERROR_CREATING_P10CR;
fixture->expected = 1;
if (!TEST_ptr(p10cr = load_csr(pkcs10_f))
|| !TEST_true(set1_newPkey(ctx, newkey))
|| !TEST_true(OSSL_CMP_CTX_set1_p10CSR(ctx, p10cr))) {
tear_down(fixture);
fixture = NULL;
}
X509_REQ_free(p10cr);
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_p10cr_null(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_P10CR;
fixture->err_code = CMP_R_ERROR_CREATING_P10CR;
fixture->expected = 0;
if (!TEST_true(set1_newPkey(fixture->cmp_ctx, newkey))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_kur(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_KUR;
fixture->err_code = CMP_R_ERROR_CREATING_KUR;
fixture->expected = 1;
if (!TEST_true(set1_newPkey(fixture->cmp_ctx, newkey))
|| !TEST_true(OSSL_CMP_CTX_set1_oldCert(fixture->cmp_ctx, cert))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_kur_without_oldcert(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->bodytype = OSSL_CMP_PKIBODY_KUR;
fixture->err_code = CMP_R_ERROR_CREATING_KUR;
fixture->expected = 0;
if (!TEST_true(set1_newPkey(fixture->cmp_ctx, newkey))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certreq_create_test, tear_down);
return result;
}
static int test_cmp_create_certconf(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->fail_info = 0;
fixture->expected = 1;
if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx,
X509_dup(cert)))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certconf_create_test, tear_down);
return result;
}
static int test_cmp_create_certconf_badAlg(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badAlg;
fixture->expected = 1;
if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx,
X509_dup(cert)))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certconf_create_test, tear_down);
return result;
}
static int test_cmp_create_certconf_fail_info_max(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_MAX;
fixture->expected = 1;
if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx,
X509_dup(cert)))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_certconf_create_test, tear_down);
return result;
}
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,
OSSL_CMP_PKIFAILUREINFO_systemFailure,
NULL);
fixture->err_code = -1;
fixture->expected = 1; /* Expected: Message creation is successful */
if (!TEST_true(set1_newPkey(fixture->cmp_ctx, newkey))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_errormsg_create_test, tear_down);
return result;
}
static int test_cmp_create_pollreq(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_pollreq_create_test, tear_down);
return result;
}
static int test_cmp_create_rr(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->expected = 1;
if (!TEST_true(OSSL_CMP_CTX_set1_oldCert(fixture->cmp_ctx, cert))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_rr_create_test, tear_down);
return result;
}
static int test_cmp_create_genm(void)
{
OSSL_CMP_ITAV *iv = NULL;
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
fixture->expected = 1;
iv = OSSL_CMP_ITAV_create(OBJ_nid2obj(NID_id_it_implicitConfirm), NULL);
if (!TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 1))
|| !TEST_ptr(iv)
|| !TEST_true(OSSL_CMP_CTX_push0_genm_ITAV(fixture->cmp_ctx, iv))) {
OSSL_CMP_ITAV_free(iv);
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_genm_create_test, tear_down);
return result;
}
static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture)
{
OSSL_CMP_CERTREPMESSAGE *crepmsg = OSSL_CMP_CERTREPMESSAGE_new();
OSSL_CMP_CERTRESPONSE *read_cresp, *cresp = OSSL_CMP_CERTRESPONSE_new();
EVP_PKEY *privkey;
X509 *certfromresp = NULL;
int res = 0;
if (crepmsg == NULL || cresp == NULL)
goto err;
if (!ASN1_INTEGER_set(cresp->certReqId, 99))
goto err;
if ((cresp->certifiedKeyPair = OSSL_CMP_CERTIFIEDKEYPAIR_new()) == NULL)
goto err;
cresp->certifiedKeyPair->certOrEncCert->type =
OSSL_CMP_CERTORENCCERT_CERTIFICATE;
if ((cresp->certifiedKeyPair->certOrEncCert->value.certificate =
X509_dup(cert)) == NULL
|| !sk_OSSL_CMP_CERTRESPONSE_push(crepmsg->response, cresp))
goto err;
cresp = NULL;
read_cresp = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, 99);
if (!TEST_ptr(read_cresp))
goto err;
if (!TEST_ptr_null(ossl_cmp_certrepmessage_get0_certresponse(crepmsg, 88)))
goto err;
privkey = OSSL_CMP_CTX_get0_newPkey(fixture->cmp_ctx, 1); /* may be NULL */
certfromresp = ossl_cmp_certresponse_get1_certificate(privkey, read_cresp);
if (certfromresp == NULL || !TEST_int_eq(X509_cmp(cert, certfromresp), 0))
goto err;
res = 1;
err:
X509_free(certfromresp);
OSSL_CMP_CERTRESPONSE_free(cresp);
OSSL_CMP_CERTREPMESSAGE_free(crepmsg);
return res;
}
static int test_cmp_create_certrep(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
EXECUTE_TEST(execute_certrep_create, tear_down);
return result;
}
static int execute_rp_create(CMP_MSG_TEST_FIXTURE *fixture)
{
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;
OSSL_CMP_MSG *rpmsg = NULL;
int res = 0;
if (si == NULL || issuer == NULL || serial == NULL)
goto err;
if (!X509_NAME_add_entry_by_txt(issuer, "CN", MBSTRING_ASC,
(unsigned char*)"The Issuer", -1, -1, 0)
|| !ASN1_INTEGER_set(serial, 99)
|| (cid = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL
|| (rpmsg = ossl_cmp_rp_new(fixture->cmp_ctx, si, cid, 1)) == NULL)
goto err;
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)))
goto err;
res = 1;
err:
ASN1_INTEGER_free(serial);
X509_NAME_free(issuer);
OSSL_CRMF_CERTID_free(cid);
OSSL_CMP_PKISI_free(si);
OSSL_CMP_MSG_free(rpmsg);
return res;
}
static int test_cmp_create_rp(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
EXECUTE_TEST(execute_rp_create, tear_down);
return result;
}
static int execute_pollrep_create(CMP_MSG_TEST_FIXTURE *fixture)
{
OSSL_CMP_MSG *pollrep;
int res = 0;
pollrep = ossl_cmp_pollRep_new(fixture->cmp_ctx, 77, 2000);
if (!TEST_ptr(pollrep))
return 0;
if (!TEST_ptr(ossl_cmp_pollrepcontent_get0_pollrep(
pollrep->body->value.pollRep, 77)))
goto err;
if (!TEST_ptr_null(ossl_cmp_pollrepcontent_get0_pollrep(
pollrep->body->value.pollRep, 88)))
goto err;
res = 1;
err:
OSSL_CMP_MSG_free(pollrep);
return res;
}
static int test_cmp_create_pollrep(void)
{
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
EXECUTE_TEST(execute_pollrep_create, tear_down);
return result;
}
static int test_cmp_pkimessage_create(int bodytype)
{
X509_REQ *p10cr = NULL;
SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
switch (fixture->bodytype = bodytype) {
case OSSL_CMP_PKIBODY_P10CR:
fixture->expected = 1;
if (!TEST_true(OSSL_CMP_CTX_set1_p10CSR(fixture->cmp_ctx,
p10cr = load_csr(pkcs10_f)))) {
tear_down(fixture);
fixture = NULL;
}
X509_REQ_free(p10cr);
break;
case OSSL_CMP_PKIBODY_IR:
case OSSL_CMP_PKIBODY_IP:
case OSSL_CMP_PKIBODY_CR:
case OSSL_CMP_PKIBODY_CP:
case OSSL_CMP_PKIBODY_KUR:
case OSSL_CMP_PKIBODY_KUP:
case OSSL_CMP_PKIBODY_RR:
case OSSL_CMP_PKIBODY_RP:
case OSSL_CMP_PKIBODY_PKICONF:
case OSSL_CMP_PKIBODY_GENM:
case OSSL_CMP_PKIBODY_GENP:
case OSSL_CMP_PKIBODY_ERROR:
case OSSL_CMP_PKIBODY_CERTCONF:
case OSSL_CMP_PKIBODY_POLLREQ:
case OSSL_CMP_PKIBODY_POLLREP:
fixture->expected = 1;
break;
default:
fixture->expected = 0;
break;
}
EXECUTE_TEST(execute_pkimessage_create_test, tear_down);
return result;
}
void cleanup_tests(void)
{
EVP_PKEY_free(newkey);
X509_free(cert);
}
int setup_tests(void)
{
if (!TEST_ptr(server_cert_f = test_get_argument(0))
|| !TEST_ptr(pkcs10_f = test_get_argument(1))) {
TEST_error("usage: cmp_msg_test server.crt pkcs10.der\n");
return 0;
}
if (!TEST_ptr(newkey = gen_rsa())
|| !TEST_ptr(cert = load_pem_cert(server_cert_f))
|| !TEST_int_eq(1, RAND_bytes(ref, sizeof(ref)))) {
cleanup_tests();
return 0;
}
/* Message creation tests */
ADD_TEST(test_cmp_create_certreq_with_invalid_bodytype);
ADD_TEST(test_cmp_create_ir_protection_fails);
ADD_TEST(test_cmp_create_ir_protection_set);
ADD_TEST(test_cmp_create_error_msg);
ADD_TEST(test_cmp_create_certconf);
ADD_TEST(test_cmp_create_certconf_badAlg);
ADD_TEST(test_cmp_create_certconf_fail_info_max);
ADD_TEST(test_cmp_create_kur);
ADD_TEST(test_cmp_create_kur_without_oldcert);
ADD_TEST(test_cmp_create_cr);
ADD_TEST(test_cmp_create_cr_without_key);
ADD_TEST(test_cmp_create_p10cr);
ADD_TEST(test_cmp_create_p10cr_null);
ADD_TEST(test_cmp_create_pollreq);
ADD_TEST(test_cmp_create_rr);
ADD_TEST(test_cmp_create_rp);
ADD_TEST(test_cmp_create_genm);
ADD_TEST(test_cmp_create_certrep);
ADD_TEST(test_cmp_create_pollrep);
ADD_ALL_TESTS_NOSUBTEST(test_cmp_pkimessage_create,
OSSL_CMP_PKIBODY_POLLREP + 1);
return 1;
}

517
test/cmp_protect_test.c Normal file
View File

@ -0,0 +1,517 @@
/*
* 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
*/
#include "cmp_testlib.h"
static const char *ir_protected_f;
static const char *ir_unprotected_f;
static const char *ip_PBM_f;
typedef struct test_fixture {
const char *test_case_name;
OSSL_CMP_CTX *cmp_ctx;
/* for protection tests */
OSSL_CMP_MSG *msg;
OSSL_CMP_PKISI *si; /* for error and response messages */
ASN1_OCTET_STRING *secret;
EVP_PKEY *privkey;
EVP_PKEY *pubkey;
unsigned char *mem;
int memlen;
X509 *cert;
STACK_OF(X509) *certs;
STACK_OF(X509) *chain;
int callback_arg;
int expected;
} CMP_PROTECT_TEST_FIXTURE;
static void tear_down(CMP_PROTECT_TEST_FIXTURE *fixture)
{
OSSL_CMP_CTX_free(fixture->cmp_ctx);
OSSL_CMP_MSG_free(fixture->msg);
ASN1_OCTET_STRING_free(fixture->secret);
OSSL_CMP_PKISI_free(fixture->si);
OPENSSL_free(fixture->mem);
sk_X509_free(fixture->certs);
sk_X509_free(fixture->chain);
OPENSSL_free(fixture);
}
static CMP_PROTECT_TEST_FIXTURE *set_up(const char *const test_case_name)
{
CMP_PROTECT_TEST_FIXTURE *fixture;
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
return NULL;
fixture->test_case_name = test_case_name;
if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new())) {
tear_down(fixture);
return NULL;
}
return fixture;
}
static EVP_PKEY *loadedprivkey = NULL;
static EVP_PKEY *loadedpubkey = NULL;
static EVP_PKEY *loadedkey = NULL;
static X509 *cert = NULL;
static unsigned char rand_data[OSSL_CMP_TRANSACTIONID_LENGTH];
static OSSL_CMP_MSG *ir_unprotected, *ir_protected;
static X509 *endentity1 = NULL, *endentity2 = NULL,
*root = NULL, *intermediate = NULL;
static int execute_calc_protection_fails_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
ASN1_BIT_STRING *protection =
ossl_cmp_calc_protection(fixture->msg, fixture->secret,
fixture->privkey);
int res = TEST_ptr_null(protection);
ASN1_BIT_STRING_free(protection);
return res;
}
static int execute_calc_protection_pbmac_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
ASN1_BIT_STRING *protection =
ossl_cmp_calc_protection(fixture->msg, fixture->secret, NULL);
int res = TEST_ptr(protection)
&& TEST_true(ASN1_STRING_cmp(protection, fixture->msg->protection) == 0);
ASN1_BIT_STRING_free(protection);
return res;
}
/*
* This function works similarly to parts of CMP_verify_signature in cmp_vfy.c,
* but without the need for a OSSL_CMP_CTX or a X509 certificate
*/
static int verify_signature(OSSL_CMP_MSG *msg,
ASN1_BIT_STRING *protection,
EVP_PKEY *pkey, int digest_nid)
{
CMP_PROTECTEDPART prot_part;
unsigned char *prot_part_der = NULL;
int len;
EVP_MD_CTX *ctx = NULL;
const EVP_MD *digest = EVP_get_digestbynid(digest_nid);
int res;
prot_part.header = OSSL_CMP_MSG_get0_header(msg);
prot_part.body = msg->body;
res =
TEST_int_ge(len = i2d_CMP_PROTECTEDPART(&prot_part, &prot_part_der), 0)
&& TEST_ptr(ctx = EVP_MD_CTX_new())
&& TEST_true(EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey))
&& TEST_int_eq(EVP_DigestVerify(ctx, protection->data,
protection->length,
prot_part_der, len), 1);
/* cleanup */
EVP_MD_CTX_free(ctx);
OPENSSL_free(prot_part_der);
return res;
}
/* Calls OSSL_CMP_calc_protection and compares and verifies signature */
static int execute_calc_protection_signature_test(CMP_PROTECT_TEST_FIXTURE *
fixture)
{
ASN1_BIT_STRING *protection =
ossl_cmp_calc_protection(fixture->msg, NULL, fixture->privkey);
int ret = (TEST_ptr(protection)
&& TEST_true(ASN1_STRING_cmp(protection,
fixture->msg->protection) == 0)
&& TEST_true(verify_signature(fixture->msg, protection,
fixture->pubkey,
fixture->cmp_ctx->digest)));
ASN1_BIT_STRING_free(protection);
return ret;
}
static int test_cmp_calc_protection_no_key_no_secret(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_unprotected_f))
|| !TEST_ptr(fixture->msg->header->protectionAlg =
X509_ALGOR_new() /* no specific alg needed here */)) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_calc_protection_fails_test, tear_down);
return result;
}
static int test_cmp_calc_protection_pkey(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->pubkey = loadedpubkey;
fixture->privkey = loadedprivkey;
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_calc_protection_signature_test, tear_down);
return result;
}
static int test_cmp_calc_protection_pbmac(void)
{
unsigned char sec_insta[] = { 'i', 'n', 's', 't', 'a' };
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
if (!TEST_ptr(fixture->secret = ASN1_OCTET_STRING_new())
|| !TEST_true(ASN1_OCTET_STRING_set
(fixture->secret, sec_insta, sizeof(sec_insta)))
|| !TEST_ptr(fixture->msg = load_pkimsg(ip_PBM_f))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_calc_protection_pbmac_test, tear_down);
return result;
}
static int execute_MSG_protect_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
return TEST_int_eq(fixture->expected,
ossl_cmp_msg_protect(fixture->cmp_ctx, fixture->msg));
}
#define SET_OPT_UNPROTECTED_SEND(ctx, val) \
OSSL_CMP_CTX_set_option((ctx), OSSL_CMP_OPT_UNPROTECTED_SEND, (val))
static int test_MSG_protect_unprotected_request(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->expected = 1;
if (!TEST_ptr(fixture->msg = OSSL_CMP_MSG_dup(ir_unprotected))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 1))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_MSG_protect_test, tear_down);
return result;
}
static int test_MSG_protect_with_msg_sig_alg_protection_plus_rsa_key(void)
{
const size_t size = sizeof(rand_data) / 2;
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->expected = 1;
if (!TEST_ptr(fixture->msg =
OSSL_CMP_MSG_dup(ir_unprotected))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 0))
/*
* Use half of the 16 bytes of random input
* for each reference and secret value
*/
|| !TEST_true(OSSL_CMP_CTX_set1_referenceValue(fixture->cmp_ctx,
rand_data, size))
|| !TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx,
rand_data + size,
size))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_MSG_protect_test, tear_down);
return result;
}
static int test_MSG_protect_with_certificate_and_key(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->expected = 1;
if (!TEST_ptr(fixture->msg =
OSSL_CMP_MSG_dup(ir_unprotected))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 0))
|| !TEST_true(OSSL_CMP_CTX_set1_pkey(fixture->cmp_ctx, loadedkey))
|| !TEST_true(OSSL_CMP_CTX_set1_clCert(fixture->cmp_ctx, cert))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_MSG_protect_test, tear_down);
return result;
}
static int test_MSG_protect_certificate_based_without_cert(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
fixture->expected = 0;
if (!TEST_ptr(fixture->msg =
OSSL_CMP_MSG_dup(ir_unprotected))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(ctx, 0))
|| !TEST_true(OSSL_CMP_CTX_set0_newPkey(ctx, 1, loadedkey))) {
tear_down(fixture);
fixture = NULL;
}
EVP_PKEY_up_ref(loadedkey);
EXECUTE_TEST(execute_MSG_protect_test, tear_down);
return result;
}
static int test_MSG_protect_no_key_no_secret(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->expected = 0;
if (!TEST_ptr(fixture->msg = OSSL_CMP_MSG_dup(ir_unprotected))
|| !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 0))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_MSG_protect_test, tear_down);
return result;
}
static int execute_MSG_add_extraCerts_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
return TEST_true(ossl_cmp_msg_add_extraCerts(fixture->cmp_ctx,
fixture->msg));
}
static int test_MSG_add_extraCerts(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
if (!TEST_ptr(fixture->msg = OSSL_CMP_MSG_dup(ir_protected))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_MSG_add_extraCerts_test, tear_down);
return result;
}
static int execute_cmp_build_cert_chain_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
STACK_OF(X509) *result = NULL;
int ret = 0;
if (TEST_ptr(result = ossl_cmp_build_cert_chain(fixture->certs,
fixture->cert))) {
/* Check whether chain built is equal to the expected one */
ret = TEST_int_eq(0, STACK_OF_X509_cmp(result, fixture->chain));
sk_X509_pop_free(result, X509_free);
}
return ret;
}
static int test_cmp_build_cert_chain(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->cert = endentity2;
if (!TEST_ptr(fixture->certs = sk_X509_new_null())
|| !TEST_ptr(fixture->chain = sk_X509_new_null())
|| !TEST_true(sk_X509_push(fixture->certs, endentity1))
|| !TEST_true(sk_X509_push(fixture->certs, root))
|| !TEST_true(sk_X509_push(fixture->certs, intermediate))
|| !TEST_true(sk_X509_push(fixture->chain, endentity2))
|| !TEST_true(sk_X509_push(fixture->chain, intermediate))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_cmp_build_cert_chain_test, tear_down);
return result;
}
static int test_cmp_build_cert_chain_missing_intermediate(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->cert = endentity2;
if (!TEST_ptr(fixture->certs = sk_X509_new_null())
|| !TEST_ptr(fixture->chain = sk_X509_new_null())
|| !TEST_true(sk_X509_push(fixture->certs, endentity1))
|| !TEST_true(sk_X509_push(fixture->certs, root))
|| !TEST_true(sk_X509_push(fixture->chain, endentity2))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_cmp_build_cert_chain_test, tear_down);
return result;
}
static int test_cmp_build_cert_chain_missing_root(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->cert = endentity2;
if (!TEST_ptr(fixture->certs = sk_X509_new_null())
|| !TEST_ptr(fixture->chain = sk_X509_new_null())
|| !TEST_true(sk_X509_push(fixture->certs, endentity1))
|| !TEST_true(sk_X509_push(fixture->certs, intermediate))
|| !TEST_true(sk_X509_push(fixture->chain, endentity2))
|| !TEST_true(sk_X509_push(fixture->chain, intermediate))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_cmp_build_cert_chain_test, tear_down);
return result;
}
static int test_cmp_build_cert_chain_no_certs(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->cert = endentity2;
if (!TEST_ptr(fixture->certs = sk_X509_new_null())
|| !TEST_ptr(fixture->chain = sk_X509_new_null())
|| !TEST_true(sk_X509_push(fixture->chain, endentity2))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_cmp_build_cert_chain_test, tear_down);
return result;
}
static int execute_X509_STORE_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
X509_STORE *store = X509_STORE_new();
STACK_OF(X509) *sk = NULL;
int res = 0;
if (!TEST_true(ossl_cmp_X509_STORE_add1_certs(store,
fixture->certs,
fixture->callback_arg)))
goto err;
sk = ossl_cmp_X509_STORE_get1_certs(store);
if (!TEST_int_eq(0, STACK_OF_X509_cmp(sk, fixture->chain)))
goto err;
res = 1;
err:
X509_STORE_free(store);
sk_X509_pop_free(sk, X509_free);
return res;
}
static int test_X509_STORE(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->callback_arg = 0; /* self-signed allowed */
if (!TEST_ptr(fixture->certs = sk_X509_new_null())
|| !sk_X509_push(fixture->certs, endentity1)
|| !sk_X509_push(fixture->certs, endentity2)
|| !sk_X509_push(fixture->certs, root)
|| !sk_X509_push(fixture->certs, intermediate)
|| !TEST_ptr(fixture->chain = sk_X509_dup(fixture->certs))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_X509_STORE_test, tear_down);
return result;
}
static int test_X509_STORE_only_self_signed(void)
{
SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
fixture->certs = sk_X509_new_null();
fixture->chain = sk_X509_new_null();
fixture->callback_arg = 1; /* only self-signed */
if (!TEST_true(sk_X509_push(fixture->certs, endentity1))
|| !TEST_true(sk_X509_push(fixture->certs, endentity2))
|| !TEST_true(sk_X509_push(fixture->certs, root))
|| !TEST_true(sk_X509_push(fixture->certs, intermediate))
|| !TEST_true(sk_X509_push(fixture->chain, root))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_X509_STORE_test, tear_down);
return result;
}
void cleanup_tests(void)
{
EVP_PKEY_free(loadedprivkey);
EVP_PKEY_free(loadedpubkey);
EVP_PKEY_free(loadedkey);
X509_free(cert);
X509_free(endentity1);
X509_free(endentity2);
X509_free(root);
X509_free(intermediate);
OSSL_CMP_MSG_free(ir_protected);
OSSL_CMP_MSG_free(ir_unprotected);
}
int setup_tests(void)
{
char *server_f;
char *server_key_f;
char *server_cert_f;
char *endentity1_f;
char *endentity2_f;
char *root_f;
char *intermediate_f;
RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH);
if (!TEST_ptr(server_f = test_get_argument(0))
|| !TEST_ptr(ir_protected_f = test_get_argument(1))
|| !TEST_ptr(ir_unprotected_f = test_get_argument(2))
|| !TEST_ptr(ip_PBM_f = test_get_argument(3))
|| !TEST_ptr(server_cert_f = test_get_argument(4))
|| !TEST_ptr(server_key_f = test_get_argument(5))
|| !TEST_ptr(endentity1_f = test_get_argument(6))
|| !TEST_ptr(endentity2_f = test_get_argument(7))
|| !TEST_ptr(root_f = test_get_argument(8))
|| !TEST_ptr(intermediate_f = test_get_argument(9))) {
TEST_error("usage: cmp_protect_test server.pem "
"IR_protected.der IR_unprotected.der IP_PBM.der "
"server.crt server.pem"
"EndEntity1.crt EndEntity2.crt "
"Root_CA.crt Intermediate_CA.crt\n");
return 0;
}
if (!TEST_ptr(loadedkey = load_pem_key(server_key_f))
|| !TEST_ptr(cert = load_pem_cert(server_cert_f)))
return 0;
if (!TEST_ptr(loadedprivkey = load_pem_key(server_f)))
return 0;
if (TEST_true(EVP_PKEY_up_ref(loadedprivkey)))
loadedpubkey = loadedprivkey;
if (!TEST_ptr(ir_protected = load_pkimsg(ir_protected_f))
|| !TEST_ptr(ir_unprotected = load_pkimsg(ir_unprotected_f)))
return 0;
if (!TEST_ptr(endentity1 = load_pem_cert(endentity1_f))
|| !TEST_ptr(endentity2 = load_pem_cert(endentity2_f))
|| !TEST_ptr(root = load_pem_cert(root_f))
|| !TEST_ptr(intermediate = load_pem_cert(intermediate_f)))
return 0;
if (!TEST_int_eq(1, RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH)))
return 0;
/* Message protection tests */
ADD_TEST(test_cmp_calc_protection_no_key_no_secret);
ADD_TEST(test_cmp_calc_protection_pkey);
ADD_TEST(test_cmp_calc_protection_pbmac);
ADD_TEST(test_MSG_protect_with_msg_sig_alg_protection_plus_rsa_key);
ADD_TEST(test_MSG_protect_with_certificate_and_key);
ADD_TEST(test_MSG_protect_certificate_based_without_cert);
ADD_TEST(test_MSG_protect_unprotected_request);
ADD_TEST(test_MSG_protect_no_key_no_secret);
ADD_TEST(test_MSG_add_extraCerts);
ADD_TEST(test_cmp_build_cert_chain);
ADD_TEST(test_cmp_build_cert_chain_missing_root);
ADD_TEST(test_cmp_build_cert_chain_missing_intermediate);
ADD_TEST(test_cmp_build_cert_chain_no_certs);
ADD_TEST(test_X509_STORE);
ADD_TEST(test_X509_STORE_only_self_signed);
return 1;
}

View File

@ -16,7 +16,7 @@
# include <openssl/pem.h>
# include <openssl/rand.h>
#include "../crypto/cmp/cmp_local.h"
# include "../crypto/cmp/cmp_local.h"
# include "testutil.h"

View File

@ -0,0 +1,24 @@
#! /usr/bin/env perl
# 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
use strict;
use OpenSSL::Test qw/:DEFAULT data_file/;
use OpenSSL::Test::Utils;
setup("test_cmp_msg");
plan skip_all => "This test is not supported in a no-cmp build"
if disabled("cmp");
plan tests => 1;
ok(run(test(["cmp_msg_test",
data_file("server.crt"),
data_file("pkcs10.der")])));

Binary file not shown.

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu
c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV
BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj
o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh
BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd
mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU
shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd
HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV
WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY
TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU
A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy
AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE
T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9
jQYqSl/ix5hn
-----END CERTIFICATE-----

View File

@ -0,0 +1,35 @@
#! /usr/bin/env perl
# 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
use strict;
use OpenSSL::Test qw/:DEFAULT data_file/;
use OpenSSL::Test::Utils;
setup("test_cmp_protect");
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 shared library build on Windows"
if $^O eq 'MSWin32' && !disabled("shared");
plan tests => 1;
ok(run(test(["cmp_protect_test",
data_file("server.pem"),
data_file("IR_protected.der"),
data_file("IR_unprotected.der"),
data_file("IP_PBM.der"),
data_file("server.crt"),
data_file("server.pem"),
data_file("EndEntity1.crt"),
data_file("EndEntity2.crt"),
data_file("Root_CA.crt"),
data_file("Intermediate_CA.crt")])));

View File

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICnDCCAYSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdSb290
IENBMB4XDTE3MTEwODE1NDgwMFoXDTE4MTEwODExMTkwMFowETEPMA0GA1UEAxMG
Q2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtNiWJufEotHe
p6E/4b0laX7K1NRamNoUokLIsq78RoBieBXaGxIdbT6zmhLnLmZdb0UN3v7FUP75
rqPN2yyj3TbS4o5ilh5El8bDDAPhW5lthCddvH/uBziRAM5oIB4xxOumNbgHpLUT
Clh49sdXd4ydYpCTWld5emRouBmMUeP/0EkyWMBIrHGSBxrqtFVRXhxvVHImQv6Z
hIKql7dCVCZbhUtxw6sLxIGL4xlhKoM2o31k4I/9tjZrWSZZ7KAIOlOLrjxZc/bQ
MwvxVUgS+C+iXzhCY8v+N/K37jwtAAk4C1aOGv/VygNcN0C/ynfKSzFmtnfei4+3
6GC7HtFzewIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQB3GYpPSCCYsJM5owKcODr/
I1aJ8jQ+u5jCKjvYLp6Cnbr4AbRXzvKuMyV6UfIAQbrGOxAClvX++5/ZQbhY+TxN
iiUM3yr5yYCLqj4MeYHhJ3gOzcppAO9LQ9V7eA8C830giZMm3cpApFSLP8CpwNUD
W/fgoQfaOae5IYPZdea88Gmt5RVNbtHgVqtm4ifTQo577kfxTeh20s+M6pgYW3/R
vftXy2ITEtk/j3NcRvOyZ7Bu1mAg7wNeUjL+gDWAaxs16LsWsCsUGwfr/Z2Rq1CF
zB0XwIyigkVLDLqDzUShcw0Eb/zYy2KXsxNWA2tb27mw+T+tmmOszpn7JjLrlVks
-----END CERTIFICATE-----

View File

@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB3zCCAZSgAwIBAgIBBjAKBggqhkjOPQQDAzAVMRMwEQYDVQQDEwpad2lzY2hl
bkNBMB4XDTE3MTEwODE2MDUwMFoXDTE4MTEwODExMTkwMFowEjEQMA4GA1UEAxMH
Q2xpZW50MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTYlibnxKLR
3qehP+G9JWl+ytTUWpjaFKJCyLKu/EaAYngV2hsSHW0+s5oS5y5mXW9FDd7+xVD+
+a6jzdsso9020uKOYpYeRJfGwwwD4VuZbYQnXbx/7gc4kQDOaCAeMcTrpjW4B6S1
EwpYePbHV3eMnWKQk1pXeXpkaLgZjFHj/9BJMljASKxxkgca6rRVUV4cb1RyJkL+
mYSCqpe3QlQmW4VLccOrC8SBi+MZYSqDNqN9ZOCP/bY2a1kmWeygCDpTi648WXP2
0DML8VVIEvgvol84QmPL/jfyt+48LQAJOAtWjhr/1coDXDdAv8p3yksxZrZ33ouP
t+hgux7Rc3sCAwEAAaMNMAswCQYDVR0TBAIwADAKBggqhkjOPQQDAwM5ADA2AhkA
qASBLwTauET6FGp/EBe7b/99jTyGB861AhkA5ILGkLX4KmjRkTcNxJ3JKB1Sumya
cbqF
-----END CERTIFICATE-----

Binary file not shown.

View File

@ -0,0 +1 @@
Reference#: 3078Secret Value: insta

Binary file not shown.

View File

@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIB1jCBv6ADAgECAgEFMA0GCSqGSIb3DQEBDQUAMBIxEDAOBgNVBAMTB1Jvb3Qg
Q0EwHhcNMTcxMTA4MTYwNDAwWhcNMTgxMTA4MTExOTAwWjAVMRMwEQYDVQQDEwpa
d2lzY2hlbkNBMEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAE9bJcmZWj2CmO6aW8
9Qylkj1WgPREf9/s4Z1VYqFODeJnebPXFBLVH/aoGxnds9E9oxAwDjAMBgNVHRME
BTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQBwQD4NTIWMMevEsSrBpKjjQEWc81Ct
eXoyAXr/d8wgVyuIZe9C7ekxPQCwowcmONUyeYQv9N2eYpdhkAQuk6DS4+aDR4s7
I6rg5R5CUGGla5NUxM0BKIS3ZIezvEGlP1NFN+HBgJI7ZIIYQ3zDr0EYgo4J7Xvm
5p58pcCZSsbVyKwKs6T+rTzOVVmJ2L1bWzywZEDmzxMkPmA6fP9XtB4Kx/b4oviw
TEQl3Jf9EkBvBkKX2rRJs7aMJo4MwOnE4HHOV5GAQqhGrXltsuXmVfIQPtRN4xlK
oNf/FukI1NcBh4A/iY4PmbyxHYmKy6qjFjng2u2VFtH15HDT4XlLP5gq
-----END CERTIFICATE-----

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICrzCCAZegAwIBAgIBATANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdSb290
IENBMB4XDTE3MTEwODE1NDUwMFoXDTE4MTEwODExMTkwMFowEjEQMA4GA1UEAxMH
Um9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALiHdLAD2Wu+
C5UDMK6WCL53Wz0CeU61RRRlGEVSqHrQOWnffgVutgftzsddxxgJJyGsqKo1B+nQ
vapyJyugYJWYNQLN5+iffe4y1UBPnHMQFHiZ4cNR6PB0eHja2wpcN3QmJzOcpRYE
xf+QQwJNFqhRi0cZGfd/JfFi/ybJalqClbnYMPcJo7g6S7M3lWbOnEOUWnbM2EBp
h849mC+kd80vXcRcb7U/3MJKK3Ee72TDye5/kWFf9zcxj2ac0oCiS66JKYobiVJr
NmbGM0I9U6T6ejXVUu2J3pGUFlcf3RCUYf1aWhkmzEzbm/FGMRJ7vVyCXm/OWIh9
bqtwH5YfljsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
AQEAF7tSa9oVan7kPR5/TXB330Ca1xQt5C38afaJbacR9mM8ZkL0HceQTuJGrnAR
4kK7CaB5iraU6Lxyql7drq8aixz/7TXna6c172J6HxDeFhQMeSt1LAh7XN5Ir6Y6
iO7XD5I5lw3Xv6qvhoD0ktkNk/WtF7aBw2ZAi+RcDMgWzWjoS4WqMbvWEHw10j9b
s8R0YG4yi6wb89UNIMfQtC2XviHKcRS9MzIJQHw73r2EY2t6o9TO+5ukHYDB6/Zo
/CLXu21MzsFvhupHgX6zdptU324tq2za1+4LvmOHSW+D36jEPT22SndXmHo5VmAn
6bQ52MhBI0rrWwju9aBpVzsUUg==
-----END CERTIFICATE-----

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu
c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV
BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj
o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh
BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd
mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU
shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd
HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV
WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY
TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU
A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy
AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE
T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9
jQYqSl/ix5hn
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZA
JHnq0ypW/PZccrWjo7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVV
pLicMnItNFElfCohBzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuW
q/vWW9r96/gBKKddmj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SO
Zf9bH1olBVsmBMsUshFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6Gv
Z/i5KOhaqgJCnRKdHHzijz9cLec5p9NSOuC1OwIDAQABAoIBAGiYVO+rIfqc38jG
sMxJED2NSBFnvE7k2LoeEgktBA0daxQgziYXtIkOXC3jkwAw1RXLuGH5RTDuJt3/
LX6nsCW3NCCB6lTGERNaJyKg4dLHpzA+juY3/2P/MKHD1bGncpV7jNk2fpV7gBY1
pu0wld1Oi+S3DPCaxs3w6Zl39Y4Z7oSNf6DRO5lGN3Asc8TSVjIOWpAl8LIg+P2B
ZvFeHRANVXaV9YmF2uEi7iMgH4vGrK2svsmM9VThVO4ArGcTRTvGYn7aw3/H4Pt+
lYuhERdpkKBT0tCgIpO5IJXMl4/5RSDTtcBwiJcReN5IHUAItBIPSHcMflNSKG/I
aQf4u0ECgYEA8+PAyzn096Y2UrKzE75yuadCveLjsUWx2NN5ZMohQru99F4k7Pab
/Te4qOe5zlxHAPK3LRwvbwUWo5mLfs45wFrSgZoRlYcCuL+JaX0y2oXMMF9E+UkY
tljMt/HpLo1SfSjN2Sae4LVhC7rWJ43LtyRepptzBPGqd26eLPGAMr8CgYEA7P8u
RGkMOrMzEKAb0A9smrzq2xW88T1VejqEt6R8mUcNt8PFHMgjuzVU4zDysrlb7G/0
VSkQWnJxBh1yNGc1Av7YgwicIgApr4ty0hZhLcnKX2VrNw+L/sSe/cnwVAc6RtPK
RR6xQubuLlrCGcbYXmyn5Jv+nlY0S3uCyDFHqIUCgYAwtpLxhJf7RwWeqva9wNJl
ZpUcHE9iPwtwxXx/tyfBjoI4Zv11HyS1BQYrJm2kXCYKeHBB4FlREXEeKDMGluZO
F1XocP+GIDtY71jg6xLXNtY76yt5pzH6ae4p53WtyKhrO1UyRFaDh3bkwuK3b8j6
wZbuLCpjGGn2BPAvBeWXPQKBgEewKN6op/pZmmi9Bay5/bAQ1TnQKYcPdnuyl9K0
/ruespeTsFw0bhqC11qhw8gsKZIri0z3TusNEwM2hQU08uQlEnkQcaoXQoTHOcQy
4NJo575Tf0r4ePBnqXA7VWcViJtEFTszPYtvLzz2VyBU9b4aP+73AN4EVW0/vx+v
SG3BAoGBAMzESFA2TXwUFmozK5zowIszc995Xqpi7mXKk77WESOpoS1dQ1wF1dSg
XOwxzFoYovLxcc1K9lqOrod8BV+qGuEfc/PIJ2aiXjvEDeZYX2eWaANNmj4OSLoJ
MNYj9tZxbq56slD7snf7AgUBnwKz0Pj6H6UsbE3gdJqZWCDyw/bB
-----END RSA PRIVATE KEY-----

View File

@ -4910,3 +4910,4 @@ d2i_X509_PUBKEY_bio ? 3_0_0 EXIST::FUNCTION:
i2d_X509_PUBKEY_bio ? 3_0_0 EXIST::FUNCTION:
RSA_get0_pss_params ? 3_0_0 EXIST::FUNCTION:RSA
X509_cmp_timeframe ? 3_0_0 EXIST::FUNCTION:
OSSL_CMP_MSG_get0_header ? 3_0_0 EXIST::FUNCTION:CMP

View File

@ -348,6 +348,8 @@ OSSL_CMP_LOG_ERR define
OSSL_CMP_LOG_INFO define
OSSL_CMP_LOG_NOTICE define
OSSL_CMP_LOG_WARNING define
OSSL_CMP_MSTR_HELPER define
OSSL_CMP_MSTR define
OSSL_CMP_alert define
OSSL_CMP_debug define
OSSL_CMP_err define