chunk 5 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/10036)
This commit is contained in:
Dr. David von Oheimb 2019-09-27 10:22:23 +02:00 committed by Matt Caswell
parent 0a4d6c6748
commit 4dde554c6a
22 changed files with 1705 additions and 23 deletions

View File

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

View File

@ -164,7 +164,7 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
{
int created = 0;
if (itav_sk_p == NULL) {
if (itav_sk_p == NULL || itav == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
goto err;
}
@ -174,11 +174,10 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
goto err;
created = 1;
}
if (itav != NULL) {
if (!sk_OSSL_CMP_ITAV_push(*itav_sk_p, itav))
goto err;
}
if (!sk_OSSL_CMP_ITAV_push(*itav_sk_p, itav))
goto err;
return 1;
err:
if (created != 0) {
sk_OSSL_CMP_ITAV_free(*itav_sk_p);

View File

@ -195,7 +195,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status)
{
if (!ossl_assert(ctx != NULL))
return 0;
return 0;
ctx->status = status;
return 1;
}

View File

@ -15,9 +15,15 @@
#ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA CMP_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS),
"error parsing pkistatus"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM),
"failure obtaining random"},
{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_SENDER_IDENTIFICATION),
"missing sender identification"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NULL_ARGUMENT), "null argument"},
{0, NULL}

377
crypto/cmp/cmp_hdr.c Normal file
View File

@ -0,0 +1,377 @@
/*
* 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 PKIHeader handling */
#include "cmp_local.h"
#include <openssl/rand.h>
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
#include <openssl/cmp.h>
#include <openssl/err.h>
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno)
{
if (!ossl_assert(hdr != NULL))
return 0;
return ASN1_INTEGER_set(hdr->pvno, pvno);
}
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr)
{
int64_t pvno;
if (!ossl_assert(hdr != NULL))
return -1;
if (!ASN1_INTEGER_get_int64(&pvno, hdr->pvno) || pvno < 0 || pvno > INT_MAX)
return -1;
return (int)pvno;
}
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr)
{
if (hdr == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return NULL;
}
return hdr->transactionID;
}
ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr)
{
if (!ossl_assert(hdr != NULL))
return NULL;
return hdr->senderNonce;
}
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr)
{
if (hdr == NULL) {
CMPerr(0, CMP_R_NULL_ARGUMENT);
return NULL;
}
return hdr->recipNonce;
}
/* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */
static int set1_general_name(GENERAL_NAME **tgt, const X509_NAME *src)
{
GENERAL_NAME *gen;
if (!ossl_assert(tgt != NULL))
return 0;
if ((gen = GENERAL_NAME_new()) == NULL)
goto err;
gen->type = GEN_DIRNAME;
if (src == NULL) { /* NULL-DN */
if ((gen->d.directoryName = X509_NAME_new()) == NULL)
goto err;
} else if (!X509_NAME_set(&gen->d.directoryName, src)) {
goto err;
}
GENERAL_NAME_free(*tgt);
*tgt = gen;
return 1;
err:
GENERAL_NAME_free(gen);
return 0;
}
/*
* Set the sender name in PKIHeader.
* when nm is NULL, sender is set to an empty string
* returns 1 on success, 0 on error
*/
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm)
{
if (!ossl_assert(hdr != NULL))
return 0;
return set1_general_name(&hdr->sender, nm);
}
int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm)
{
if (!ossl_assert(hdr != NULL))
return 0;
return set1_general_name(&hdr->recipient, nm);
}
int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr)
{
if (!ossl_assert(hdr != NULL))
return 0;
if (hdr->messageTime == NULL
&& (hdr->messageTime = ASN1_GENERALIZEDTIME_new()) == NULL)
return 0;
return ASN1_GENERALIZEDTIME_set(hdr->messageTime, time(NULL)) != NULL;
}
/* assign to *tgt a copy of src (or if NULL a random byte array of given len) */
static int set1_aostr_else_random(ASN1_OCTET_STRING **tgt,
const ASN1_OCTET_STRING *src, size_t len)
{
unsigned char *bytes = NULL;
int res = 0;
if (src == NULL) { /* generate a random value if src == NULL */
if ((bytes = OPENSSL_malloc(len)) == NULL)
goto err;
if (RAND_bytes(bytes, len) <= 0) {
CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM);
goto err;
}
res = ossl_cmp_asn1_octet_string_set1_bytes(tgt, bytes, len);
} else {
res = ossl_cmp_asn1_octet_string_set1(tgt, src);
}
err:
OPENSSL_free(bytes);
return res;
}
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
const ASN1_OCTET_STRING *senderKID)
{
if (!ossl_assert(hdr != NULL))
return 0;
return ossl_cmp_asn1_octet_string_set1(&hdr->senderKID, senderKID);
}
/* push the given text string to the given PKIFREETEXT ft */
int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text)
{
ASN1_UTF8STRING *utf8string;
if (!ossl_assert(ft != NULL && text != NULL))
return 0;
if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
return 0;
if (!ASN1_STRING_set(utf8string, text, -1))
goto err;
if (!sk_ASN1_UTF8STRING_push(ft, utf8string))
goto err;
return 1;
err:
ASN1_UTF8STRING_free(utf8string);
return 0;
}
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
{
if (!ossl_assert(hdr != NULL && text != NULL))
return 0;
if (hdr->freeText == NULL
&& (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL)
return 0;
return sk_ASN1_UTF8STRING_push(hdr->freeText, text);
}
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
{
if (!ossl_assert(hdr != NULL && text != NULL))
return 0;
if (hdr->freeText == NULL
&& (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL)
return 0;
return ossl_cmp_pkifreetext_push_str(hdr->freeText, (char *)text->data);
}
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
OSSL_CMP_ITAV *itav)
{
if (!ossl_assert(hdr != NULL && itav != NULL))
return 0;
return OSSL_CMP_ITAV_push0_stack_item(&hdr->generalInfo, itav);
}
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i;
OSSL_CMP_ITAV *itav;
if (!ossl_assert(hdr != NULL))
return 0;
for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i));
if (itav == NULL)
return 0;
if (!ossl_cmp_hdr_generalInfo_push0_item(hdr, itav)) {
OSSL_CMP_ITAV_free(itav);
return 0;
}
}
return 1;
}
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr)
{
OSSL_CMP_ITAV *itav;
ASN1_TYPE *asn1null;
if (!ossl_assert(hdr != NULL))
return 0;
asn1null = (ASN1_TYPE *)ASN1_NULL_new();
if (asn1null == NULL)
return 0;
if ((itav = OSSL_CMP_ITAV_create(OBJ_nid2obj(NID_id_it_implicitConfirm),
asn1null)) == NULL)
goto err;
if (!ossl_cmp_hdr_generalInfo_push0_item(hdr, itav))
goto err;
return 1;
err:
ASN1_TYPE_free(asn1null);
OSSL_CMP_ITAV_free(itav);
return 0;
}
/* return 1 if implicitConfirm in the generalInfo field of the header is set */
int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
{
int itavCount;
int i;
OSSL_CMP_ITAV *itav;
if (!ossl_assert(hdr != NULL))
return 0;
itavCount = sk_OSSL_CMP_ITAV_num(hdr->generalInfo);
for (i = 0; i < itavCount; i++) {
itav = sk_OSSL_CMP_ITAV_value(hdr->generalInfo, i);
if (itav != NULL
&& OBJ_obj2nid(itav->infoType) == NID_id_it_implicitConfirm)
return 1;
}
return 0;
}
/* fill in all fields of the hdr according to the info given in ctx */
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
{
X509_NAME *sender;
X509_NAME *rcp = NULL;
if (!ossl_assert(ctx != NULL && hdr != NULL))
return 0;
/* set the CMP version */
if (!ossl_cmp_hdr_set_pvno(hdr, OSSL_CMP_PVNO))
return 0;
sender = ctx->clCert != NULL ?
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
/*
* The sender name is copied from the subject of the client cert, if any,
* or else from the the subject name provided for certification requests.
* As required by RFC 4210 section 5.1.1., if the sender name is not known
* to the client it set to NULL-DN. In this case for identification at least
* the senderKID must be set, which we take from any referenceValue given.
*/
if (sender == NULL && ctx->referenceValue == NULL) {
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);
return 0;
}
if (!ossl_cmp_hdr_set1_sender(hdr, sender))
return 0;
/* determine recipient entry in PKIHeader */
if (ctx->srvCert != NULL) {
rcp = X509_get_subject_name(ctx->srvCert);
/* set also as expected_sender of responses unless set explicitly */
if (ctx->expected_sender == NULL && rcp != NULL
&& !OSSL_CMP_CTX_set1_expected_sender(ctx, rcp))
return 0;
} else if (ctx->recipient != NULL) {
rcp = ctx->recipient;
} else if (ctx->issuer != NULL) {
rcp = ctx->issuer;
} else if (ctx->oldCert != NULL) {
rcp = X509_get_issuer_name(ctx->oldCert);
} else if (ctx->clCert != NULL) {
rcp = X509_get_issuer_name(ctx->clCert);
}
if (!ossl_cmp_hdr_set1_recipient(hdr, rcp))
return 0;
/* set current time as message time */
if (!ossl_cmp_hdr_update_messageTime(hdr))
return 0;
if (ctx->recipNonce != NULL
&& !ossl_cmp_asn1_octet_string_set1(&hdr->recipNonce,
ctx->recipNonce))
return 0;
/*
* set ctx->transactionID in CMP header
* if ctx->transactionID is NULL, a random one is created with 128 bit
* according to section 5.1.1:
*
* It is RECOMMENDED that the clients fill the transactionID field with
* 128 bits of (pseudo-) random data for the start of a transaction to
* reduce the probability of having the transactionID in use at the server.
*/
if (ctx->transactionID == NULL
&& !set1_aostr_else_random(&ctx->transactionID, NULL,
OSSL_CMP_TRANSACTIONID_LENGTH))
return 0;
if (!ossl_cmp_asn1_octet_string_set1(&hdr->transactionID,
ctx->transactionID))
return 0;
/*-
* set random senderNonce
* according to section 5.1.1:
*
* senderNonce present
* -- 128 (pseudo-)random bits
* The senderNonce and recipNonce fields protect the PKIMessage against
* replay attacks. The senderNonce will typically be 128 bits of
* (pseudo-) random data generated by the sender, whereas the recipNonce
* is copied from the senderNonce of the previous message in the
* transaction.
*/
if (!set1_aostr_else_random(&hdr->senderNonce, NULL,
OSSL_CMP_SENDERNONCE_LENGTH))
return 0;
/* store senderNonce - for cmp with recipNonce in next outgoing msg */
if (!OSSL_CMP_CTX_set1_senderNonce(ctx, hdr->senderNonce))
return 0;
/*-
* freeText [7] PKIFreeText OPTIONAL,
* -- this may be used to indicate context-specific instructions
* -- (this field is intended for human consumption)
*/
if (ctx->freeText != NULL
&& !ossl_cmp_hdr_push1_freeText(hdr, ctx->freeText))
return 0;
return 1;
}

View File

@ -77,6 +77,7 @@ struct ossl_cmp_ctx_st {
ASN1_OCTET_STRING *transactionID; /* the current transaction ID */
ASN1_OCTET_STRING *senderNonce; /* last nonce sent */
ASN1_OCTET_STRING *recipNonce; /* last nonce received */
ASN1_UTF8STRING *freeText; /* optional string to include each msg */
STACK_OF(OSSL_CMP_ITAV) *geninfo_ITAVs;
int implicitConfirm; /* set implicitConfirm in IR/KUR/CR messages */
int disableConfirm; /* disable certConf in IR/KUR/CR for broken servers */
@ -720,6 +721,35 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
const ASN1_OCTET_STRING *nonce);
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
/* from cmp_status.c */
OSSL_CMP_PKISI *
ossl_cmp_statusinfo_new(int status, int fail_info, const char *text);
int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *statusInfo);
const char *ossl_cmp_PKIStatus_to_string(int status);
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si);
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index);
/* from cmp_hdr.c */
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
const ASN1_OCTET_STRING *senderKID);
int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text);
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
OSSL_CMP_ITAV *itav);
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
STACK_OF(OSSL_CMP_ITAV) *itavs);
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
# define OSSL_CMP_SENDERNONCE_LENGTH 16
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */

302
crypto/cmp/cmp_status.c Normal file
View File

@ -0,0 +1,302 @@
/*
* 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 PKIStatusInfo handling and PKIMessage decomposition */
#include <string.h>
#include "cmp_local.h"
/* explicit #includes not strictly needed since implied by the above: */
#include <time.h>
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h> /* needed in case config no-deprecated */
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/asn1err.h> /* for ASN1_R_TOO_SMALL and ASN1_R_TOO_LARGE */
/* CMP functions related to PKIStatus */
int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *si)
{
if (!ossl_assert(si != NULL && si->status != NULL))
return -1;
return ossl_cmp_asn1_get_int(si->status);
}
/*
* return the declared identifier and a short explanation for the PKIStatus
* value as specified in RFC4210, Appendix F.
*/
const char *ossl_cmp_PKIStatus_to_string(int status)
{
switch (status) {
case OSSL_CMP_PKISTATUS_accepted:
return "PKIStatus: accepted";
case OSSL_CMP_PKISTATUS_grantedWithMods:
return "PKIStatus: granted with modifications";
case OSSL_CMP_PKISTATUS_rejection:
return "PKIStatus: rejection";
case OSSL_CMP_PKISTATUS_waiting:
return "PKIStatus: waiting";
case OSSL_CMP_PKISTATUS_revocationWarning:
return "PKIStatus: revocation warning - a revocation of the cert is imminent";
case OSSL_CMP_PKISTATUS_revocationNotification:
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:
{
char buf[40];
BIO_snprintf(buf, sizeof(buf), "PKIStatus: invalid=%d", status);
CMPerr(0, CMP_R_ERROR_PARSING_PKISTATUS);
ossl_cmp_add_error_data(buf);
return NULL;
}
}
}
/*
* returns a pointer to the statusString contained in a PKIStatusInfo
* returns NULL on error
*/
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si)
{
if (!ossl_assert(si != NULL))
return NULL;
return si->statusString;
}
/*
* returns the FailureInfo bits of the given PKIStatusInfo
* returns -1 on error
*/
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si)
{
int i;
int res = 0;
if (!ossl_assert(si != NULL && si->failInfo != NULL))
return -1;
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++)
if (ASN1_BIT_STRING_get_bit(si->failInfo, i))
res |= 1 << i;
return res;
}
/*
* internal function
* convert PKIFailureInfo number to human-readable string
*
* returns pointer to static string
* returns NULL on error
*/
static const char *CMP_PKIFAILUREINFO_to_string(int number)
{
switch (number) {
case OSSL_CMP_PKIFAILUREINFO_badAlg:
return "badAlg";
case OSSL_CMP_PKIFAILUREINFO_badMessageCheck:
return "badMessageCheck";
case OSSL_CMP_PKIFAILUREINFO_badRequest:
return "badRequest";
case OSSL_CMP_PKIFAILUREINFO_badTime:
return "badTime";
case OSSL_CMP_PKIFAILUREINFO_badCertId:
return "badCertId";
case OSSL_CMP_PKIFAILUREINFO_badDataFormat:
return "badDataFormat";
case OSSL_CMP_PKIFAILUREINFO_wrongAuthority:
return "wrongAuthority";
case OSSL_CMP_PKIFAILUREINFO_incorrectData:
return "incorrectData";
case OSSL_CMP_PKIFAILUREINFO_missingTimeStamp:
return "missingTimeStamp";
case OSSL_CMP_PKIFAILUREINFO_badPOP:
return "badPOP";
case OSSL_CMP_PKIFAILUREINFO_certRevoked:
return "certRevoked";
case OSSL_CMP_PKIFAILUREINFO_certConfirmed:
return "certConfirmed";
case OSSL_CMP_PKIFAILUREINFO_wrongIntegrity:
return "wrongIntegrity";
case OSSL_CMP_PKIFAILUREINFO_badRecipientNonce:
return "badRecipientNonce";
case OSSL_CMP_PKIFAILUREINFO_timeNotAvailable:
return "timeNotAvailable";
case OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy:
return "unacceptedPolicy";
case OSSL_CMP_PKIFAILUREINFO_unacceptedExtension:
return "unacceptedExtension";
case OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable:
return "addInfoNotAvailable";
case OSSL_CMP_PKIFAILUREINFO_badSenderNonce:
return "badSenderNonce";
case OSSL_CMP_PKIFAILUREINFO_badCertTemplate:
return "badCertTemplate";
case OSSL_CMP_PKIFAILUREINFO_signerNotTrusted:
return "signerNotTrusted";
case OSSL_CMP_PKIFAILUREINFO_transactionIdInUse:
return "transactionIdInUse";
case OSSL_CMP_PKIFAILUREINFO_unsupportedVersion:
return "unsupportedVersion";
case OSSL_CMP_PKIFAILUREINFO_notAuthorized:
return "notAuthorized";
case OSSL_CMP_PKIFAILUREINFO_systemUnavail:
return "systemUnavail";
case OSSL_CMP_PKIFAILUREINFO_systemFailure:
return "systemFailure";
case OSSL_CMP_PKIFAILUREINFO_duplicateCertReq:
return "duplicateCertReq";
default:
return NULL; /* illegal failure number */
}
}
/*
* checks PKIFailureInfo bits in a given PKIStatusInfo
* returns 1 if a given bit is set, 0 if not, -1 on error
*/
int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index)
{
if (!ossl_assert(si != NULL && si->failInfo != NULL))
return -1;
if (bit_index < 0 || bit_index > OSSL_CMP_PKIFAILUREINFO_MAX) {
CMPerr(0, CMP_R_INVALID_ARGS);
return -1;
}
return ASN1_BIT_STRING_get_bit(si->failInfo, bit_index);
}
/*
* place human-readable error string created from PKIStatusInfo in given buffer
* returns pointer to the same buffer containing the string, or NULL on error
*/
char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
size_t bufsize)
{
int status, failure, fail_info;
const char *status_string, *failure_string;
OSSL_CMP_PKIFREETEXT *status_strings;
ASN1_UTF8STRING *text;
int i;
int printed_chars;
int failinfo_found = 0;
int n_status_strings;
char* write_ptr = buf;
#define ADVANCE_BUFFER \
if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \
return NULL; \
write_ptr += printed_chars; \
bufsize -= printed_chars;
if (ctx == NULL
|| buf == NULL
|| (status = OSSL_CMP_CTX_get_status(ctx)) < 0
|| (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL)
return NULL;
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string);
ADVANCE_BUFFER;
/* failInfo is optional and may be empty */
if ((fail_info = OSSL_CMP_CTX_get_failInfoCode(ctx)) > 0) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: ");
ADVANCE_BUFFER;
for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) {
if ((fail_info & (1 << failure)) != 0) {
failure_string = CMP_PKIFAILUREINFO_to_string(failure);
if (failure_string != NULL) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s",
failure > 0 ? ", " : "",
failure_string);
ADVANCE_BUFFER;
failinfo_found = 1;
}
}
}
}
if (!failinfo_found && status != OSSL_CMP_PKISTATUS_accepted
&& status != OSSL_CMP_PKISTATUS_grantedWithMods) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "; <no failure info>");
ADVANCE_BUFFER;
}
/* statusString sequence is optional and may be empty */
status_strings = OSSL_CMP_CTX_get0_statusString(ctx);
n_status_strings = sk_ASN1_UTF8STRING_num(status_strings);
if (n_status_strings > 0) {
printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ",
n_status_strings > 1 ? "s" : "");
ADVANCE_BUFFER;
for (i = 0; i < n_status_strings; i++) {
text = sk_ASN1_UTF8STRING_value(status_strings, i);
printed_chars = BIO_snprintf(write_ptr, bufsize, "\"%s\"%s",
ASN1_STRING_get0_data(text),
i < n_status_strings - 1 ? ", " : "");
ADVANCE_BUFFER;
}
}
#undef ADVANCE_BUFFER
return buf;
}
/*
* Creates a new PKIStatusInfo structure and fills it in
* returns a pointer to the structure on success, NULL on error
* note: strongly overlaps with TS_RESP_CTX_set_status_info()
* and TS_RESP_CTX_add_failure_info() in ../ts/ts_rsp_sign.c
*/
OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
const char *text)
{
OSSL_CMP_PKISI *si = OSSL_CMP_PKISI_new();
ASN1_UTF8STRING *utf8_text = NULL;
int failure;
if (si == NULL)
goto err;
if (!ASN1_INTEGER_set(si->status, status))
goto err;
if (text != NULL) {
if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
|| !ASN1_STRING_set(utf8_text, text, -1))
goto err;
if ((si->statusString = sk_ASN1_UTF8STRING_new_null()) == NULL)
goto err;
if (!sk_ASN1_UTF8STRING_push(si->statusString, utf8_text))
goto err;
/* Ownership is lost. */
utf8_text = NULL;
}
for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) {
if ((fail_info & (1 << failure)) != 0) {
if (si->failInfo == NULL
&& (si->failInfo = ASN1_BIT_STRING_new()) == NULL)
goto err;
if (!ASN1_BIT_STRING_set_bit(si->failInfo, failure, 1))
goto err;
}
}
return si;
err:
OSSL_CMP_PKISI_free(si);
ASN1_UTF8STRING_free(utf8_text);
return NULL;
}

View File

@ -2063,8 +2063,11 @@ 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_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
CMP_R_INVALID_ARGS:100:invalid args
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification
CMP_R_NO_STDIO:194:no stdio
CMP_R_NULL_ARGUMENT:103:null argument
CMS_R_ADD_SIGNER_ERROR:99:add signer error

View File

@ -0,0 +1,127 @@
=pod
=head1 NAME
ossl_cmp_hdr_set_pvno,
ossl_cmp_hdr_get_pvno,
ossl_cmp_hdr_get0_sendernonce,
ossl_cmp_hdr_set1_sender,
ossl_cmp_hdr_set1_recipient,
ossl_cmp_hdr_update_messagetime,
ossl_cmp_hdr_set1_senderKID,
ossl_cmp_hdr_push0_freeText,
ossl_cmp_hdr_push1_freeText,
ossl_cmp_hdr_generalinfo_item_push0,
ossl_cmp_hdr_generalinfo_items_push1,
ossl_cmp_hdr_set_implicitConfirm,
ossl_cmp_hdr_check_implicitConfirm,
ossl_cmp_hdr_init
- functions manipulating CMP message headers
=head1 SYNOPSIS
#include "cmp_int.h"
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
ASN1_OCTET_STRING
*ossl_cmp_hdr_get0_sendernonce(const OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
int ossl_cmp_hdr_update_messagetime(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
const ASN1_OCTET_STRING *senderKID);
int ossl_cmp_hdr_generalinfo_item_push0(OSSL_CMP_PKIHEADER *hdr,
OSSL_CMP_ITAV *itav);
int ossl_cmp_hdr_generalinfo_items_push1(OSSL_CMP_PKIHEADER *hdr,
STACK_OF(OSSL_CMP_ITAV) *itavs);
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr,
ASN1_UTF8STRING *text);
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr,
ASN1_UTF8STRING *text);
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_check_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
=head1 DESCRIPTION
ossl_cmp_hdr_set_pvno() sets hdr->pvno to the given B<pvno>.
ossl_cmp_hdr_get_pvno() returns the pvno of the given B<hdr> or -1 on error.
ossl_cmp_hdr_get0_sendernonce() returns the sender nonce of the given PKIHeader.
ossl_cmp_hdr_set1_sender() sets the sender field in the given PKIHeader
to the given X509 Name value, without consuming the pointer.
ossl_cmp_hdr_set1_recipient() sets the recipient field in the given
PKIHeader to the given X509 Name value, without consuming the pointer.
If B<nm> is NULL, recipient is set to the NULL DN (the empty list of strings).
ossl_cmp_hdr_update_messagetime() (re-)sets the messageTime to the current
system time. As written in RFC 4210, section 5.1.1:
The messageTime field contains the time at which the sender created the message.
This may be useful to allow end entities to correct/check their local time for
consistency with the time on a central system.
ossl_cmp_hdr_set1_senderKID() Sets hdr->senderKID to the given string.
In an PBMAC-protected IR this usually is a reference number issued by the CA,
else the subject key ID of the sender's protecting certificate.
ossl_cmp_hdr_push0_freeText() pushes an ASN1_UTF8STRING to
hdr->freeText and consumes the given pointer.
ossl_cmp_hdr_push1_freeText() pushes an ASN1_UTF8STRING to
hdr->freeText and does not consume the pointer.
ossl_cmp_hdr_generalinfo_item_push0() adds the given InfoTypeAndValue
item to the hdr->generalInfo stack. Consumes the B<itav> pointer.
ossl_cmp_hdr_generalinfo_items_push1() adds a copy of the B<itavs> stack to
the generalInfo field of PKIheader of the B<hdr>. Does not consume the B<itavs>
pointer.
ossl_cmp_hdr_set_implicitConfirm() sets implicitConfirm in the generalInfo field
of the PKIMessage header.
ossl_cmp_hdr_check_implicitConfirm() returns 1 if implicitConfirm is
set int generalInfo field of the given PKIMessage header, 0 if not.
ossl_cmp_hdr_init() initializes a PKIHeader structure based on the
values in the given OSSL_CMP_CTX structure.
This starts a new transaction in case ctx->transactionID is NULL.
The sender name is copied from the subject of the client cert, if any,
or else from the subject name provided for certification requests.
As required by RFC 4210 section 5.1.1., if the sender name is not known
to the client it set to the NULL-DN. In this case for identification at least
the senderKID must be set, which we take from any referenceValue provided.
=head1 NOTES
CMP is defined in RFC 4210 (and CRMF in RFC 4211).
=head1 RETURN VALUES
ossl_cmp_hdr_get_pvno() returns the pvno of the given B<hdr> or -1 on error.
ossl_cmp_hdr_get0_sendernonce() returns the respective nonce.
All other functions return 1 on success, 0 on error.
See the individual functions above.
=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

@ -0,0 +1,107 @@
=pod
=head1 NAME
ossl_cmp_statusinfo_new,
ossl_cmp_pkisi_pkistatus_get,
ossl_cmp_pkisi_pkifailureinfo_get,
ossl_cmp_pkisi_pkifailureinfo_check,
ossl_cmp_pkisi_failinfo_get0,
ossl_cmp_pkisi_statusstring_get0,
ossl_pkisi_snprint
- functions for managing PKI status information
=head1 SYNOPSIS
#include "cmp.h"
# define OSSL_CMP_PKIFAILUREINFO_badAlg 0
# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1
# define OSSL_CMP_PKIFAILUREINFO_badRequest 2
# define OSSL_CMP_PKIFAILUREINFO_badTime 3
# define OSSL_CMP_PKIFAILUREINFO_badCertId 4
# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5
# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6
# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7
# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8
# define OSSL_CMP_PKIFAILUREINFO_badPOP 9
# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10
# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11
# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12
# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13
# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14
# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15
# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16
# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17
# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18
# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19
# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20
# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21
# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22
# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23
# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24
# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25
# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26
# define OSSL_CMP_PKIFAILUREINFO_MAX 26
OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
const char *text);
int ossl_cmp_pkisi_pkistatus_get(OSSL_CMP_PKISI *si);
int ossl_cmp_pkisi_pkifailureinfo_get(OSSL_CMP_PKISI *si);
int ossl_cmp_pkisi_pkifailureinfo_check(OSSL_CMP_PKISI *si, int bit_index);
OSSL_CMP_PKIFAILUREINFO *ossl_cmp_pkisi_failinfo_get0(const OSSL_CMP_PKISI *si);
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_statusstring_get0(const OSSL_CMP_PKISI *si);
char *ossl_pkisi_snprint(OSSL_CMP_PKISI *si, char *buf, int bufsize);
=head1 DESCRIPTION
ossl_cmp_statusinfo_new() creates a new PKIStatusInfo structure and fills it
with the given values. It sets the status field to B<status>.
If B<text> is not NULL, it is copied to statusString.
B<fail_info> is is interpreted as bit pattern for the failInfo field.
Returns a pointer to the structure on success, or NULL on error.
ossl_cmp_pkisi_pkistatus_get() returns the PKIStatus of B<si>, or -1 on error.
ossl_cmp_pkisi_pkifailureinfo_get() returns the PKIFailureInfo bits
of B<si>, encoded as integer, or -1 on error.
ossl_cmp_pkisi_pkifailureinfo_check() returns the state of the bit (0 or 1)
with index B<bit_index> in the PKIFailureInfo of the B<si>, or -1 on error.
ossl_cmp_pkisi_failinfo_get0() returns a direct pointer to the failInfo
field contained in B<si>, or NULL on error.
ossl_cmp_pkisi_statusstring_get0() returns a direct pointer to the statusString
field contained in B<si>.
ossl_pkisi_snprint() places at max B<bufsize> characters of human-readable
error string of B<si> in pre-allocated B<buf>. Returns pointer to the same
B<buf> containing the string, or NULL on error.
=head1 NOTES
CMP is defined in RFC 4210 (and CRMF in RFC 4211).
=head1 RETURN VALUES
See the individual functions above.
=head1 SEE ALSO
L<OSSL_CMP_CTX_new(3)>, L<ossl_cmp_certreq_new(3)>
=head1 HISTORY
The OpenSSL CMP support was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,46 @@
=pod
=head1 NAME
OSSL_CMP_CTX_snprint_PKIStatus
- function(s) for managing the CMP PKIStatus
=head1 SYNOPSIS
#include <openssl/cmp.h>
char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf, int bufsize);
=head1 DESCRIPTION
This is the PKIStatus API for using CMP (Certificate Management Protocol) with
OpenSSL.
OSSL_CMP_CTX_snprint_PKIStatus() takes the PKIStatusInfo components contained
in the given CMP context and places a human-readable string created from them
in the given buffer, with the given maximal length.
On success it returns a copy of the buffer pointer containing the string.
=head1 NOTES
CMP is defined in RFC 4210 (and CRMF in RFC 4211).
=head1 RETURN VALUES
OSSL_CMP_CTX_snprint_PKIStatus()
returns the intended pointer value as described above or NULL on error.
=head1 HISTORY
The OpenSSL CMP support was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,47 @@
=pod
=head1 NAME
OSSL_CMP_HDR_get0_transactionID,
OSSL_CMP_HDR_get0_recipNonce
- functions manipulating CMP message headers
=head1 SYNOPSIS
#include <openssl/cmp.h>
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);
=head1 DESCRIPTION
OSSL_CMP_HDR_get0_transactionID returns the transaction ID of the given
PKIHeader.
OSSL_CMP_HDR_get0_recipNonce returns the recipient nonce of the given PKIHeader.
=head1 NOTES
CMP is defined in RFC 4210.
=head1 RETURN VALUES
The functions return 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

@ -337,6 +337,15 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
const ASN1_OCTET_STRING *nonce);
/* from cmp_status.c */
char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
size_t bufsize);
/* from cmp_hdr.c */
/* support application-level CMP debugging in cmp.c: */
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr);
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr);
# ifdef __cplusplus
}
# endif

View File

@ -33,8 +33,11 @@ int ERR_load_CMP_strings(void);
/*
* CMP reason codes.
*/
# define CMP_R_ERROR_PARSING_PKISTATUS 107
# define CMP_R_FAILURE_OBTAINING_RANDOM 110
# define CMP_R_INVALID_ARGS 100
# define CMP_R_MULTIPLE_SAN_SOURCES 102
# define CMP_R_MISSING_SENDER_IDENTIFICATION 111
# define CMP_R_NO_STDIO 194
# define CMP_R_NULL_ARGUMENT 103

View File

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

@ -24,21 +24,10 @@ typedef struct test_fixture {
static CMP_ASN_TEST_FIXTURE *set_up(const char *const test_case_name)
{
CMP_ASN_TEST_FIXTURE *fixture;
int setup_ok = 0;
/* Allocate memory owned by the fixture, exit on error */
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
goto err;
return NULL;
fixture->test_case_name = test_case_name;
setup_ok = 1;
err:
if (!setup_ok) {
#ifndef OPENSSL_NO_STDIO
ERR_print_errors_fp(stderr);
#endif
exit(EXIT_FAILURE);
}
return fixture;
}
@ -121,6 +110,7 @@ void cleanup_tests(void)
int setup_tests(void)
{
RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH);
/* ASN.1 related tests */
ADD_TEST(test_cmp_asn1_get_int);
ADD_TEST(test_ASN1_OCTET_STRING_set);

View File

@ -29,8 +29,9 @@ static OSSL_CMP_CTX_TEST_FIXTURE *set_up(const char *const test_case_name)
{
OSSL_CMP_CTX_TEST_FIXTURE *fixture;
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))
|| !TEST_ptr(fixture->ctx = OSSL_CMP_CTX_new())) {
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
return NULL;
if (!TEST_ptr(fixture->ctx = OSSL_CMP_CTX_new())) {
tear_down(fixture);
return NULL;
}

468
test/cmp_hdr_test.c Normal file
View File

@ -0,0 +1,468 @@
/*
* 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 unsigned char rand_data[OSSL_CMP_TRANSACTIONID_LENGTH];
typedef struct test_fixture {
const char *test_case_name;
int expected;
OSSL_CMP_CTX *cmp_ctx;
OSSL_CMP_PKIHEADER *hdr;
} CMP_HDR_TEST_FIXTURE;
static void tear_down(CMP_HDR_TEST_FIXTURE *fixture)
{
OSSL_CMP_PKIHEADER_free(fixture->hdr);
OSSL_CMP_CTX_free(fixture->cmp_ctx);
OPENSSL_free(fixture);
}
static CMP_HDR_TEST_FIXTURE *set_up(const char *const test_case_name)
{
CMP_HDR_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()))
goto err;
if (!TEST_ptr(fixture->hdr = OSSL_CMP_PKIHEADER_new()))
goto err;
return fixture;
err:
tear_down(fixture);
return NULL;
}
static int execute_HDR_set_get_pvno_test(CMP_HDR_TEST_FIXTURE *fixture)
{
int pvno = 77;
if (!TEST_int_eq(ossl_cmp_hdr_set_pvno(fixture->hdr, pvno), 1))
return 0;
if (!TEST_int_eq(ossl_cmp_hdr_get_pvno(fixture->hdr), pvno))
return 0;
return 1;
}
static int test_HDR_set_get_pvno(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_set_get_pvno_test, tear_down);
return result;
}
#define X509_NAME_ADD(n, rd, s) X509_NAME_add_entry_by_txt((n), (rd), \
MBSTRING_ASC, (unsigned char *)(s), -1, -1, 0)
static int execute_HDR_get0_senderNonce_test(CMP_HDR_TEST_FIXTURE *fixture)
{
X509_NAME *sender = X509_NAME_new();
ASN1_OCTET_STRING *sn;
if (!TEST_ptr(sender))
return 0;
X509_NAME_ADD(sender, "CN", "A common sender name");
if (!TEST_int_eq(OSSL_CMP_CTX_set1_subjectName(fixture->cmp_ctx, sender),
1))
return 0;
if (!TEST_int_eq(ossl_cmp_hdr_init(fixture->cmp_ctx, fixture->hdr),
1))
return 0;
sn = ossl_cmp_hdr_get0_senderNonce(fixture->hdr);
if (!TEST_int_eq(ASN1_OCTET_STRING_cmp(fixture->cmp_ctx->senderNonce, sn),
0))
return 0;
X509_NAME_free(sender);
return 1;
}
static int test_HDR_get0_senderNonce(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_get0_senderNonce_test, tear_down);
return result;
}
static int execute_HDR_set1_sender_test(CMP_HDR_TEST_FIXTURE *fixture)
{
X509_NAME *x509name = X509_NAME_new();
if (!TEST_ptr(x509name))
return 0;
X509_NAME_ADD(x509name, "CN", "A common sender name");
if (!TEST_int_eq(ossl_cmp_hdr_set1_sender(fixture->hdr, x509name), 1))
return 0;
if (!TEST_int_eq(fixture->hdr->sender->type, GEN_DIRNAME))
return 0;
if (!TEST_int_eq(
X509_NAME_cmp(fixture->hdr->sender->d.directoryName, x509name), 0))
return 0;
X509_NAME_free(x509name);
return 1;
}
static int test_HDR_set1_sender(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_set1_sender_test, tear_down);
return result;
}
static int execute_HDR_set1_recipient_test(CMP_HDR_TEST_FIXTURE *fixture)
{
X509_NAME *x509name = X509_NAME_new();
if (!TEST_ptr(x509name))
return 0;
X509_NAME_ADD(x509name, "CN", "A common recipient name");
if (!TEST_int_eq(ossl_cmp_hdr_set1_recipient(fixture->hdr, x509name), 1))
return 0;
if (!TEST_int_eq(fixture->hdr->recipient->type, GEN_DIRNAME))
return 0;
if (!TEST_int_eq(
X509_NAME_cmp(fixture->hdr->recipient->d.directoryName, x509name),0))
return 0;
X509_NAME_free(x509name);
return 1;
}
static int test_HDR_set1_recipient(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_set1_recipient_test, tear_down);
return result;
}
static int execute_HDR_update_messageTime_test(CMP_HDR_TEST_FIXTURE *fixture)
{
struct tm hdrtm;
time_t hdrtime, before, after, now;
now = time(NULL);
before = mktime(gmtime(&now));
if (!TEST_true(ossl_cmp_hdr_update_messageTime(fixture->hdr)))
return 0;
if (!TEST_true(ASN1_TIME_to_tm(fixture->hdr->messageTime, &hdrtm)))
return 0;
hdrtime = mktime(&hdrtm);
if (!TEST_true(before <= hdrtime))
return 0;
now = time(NULL);
after = mktime(gmtime(&now));
return TEST_true(hdrtime <= after);
}
static int test_HDR_update_messageTime(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_update_messageTime_test, tear_down);
return result;
}
static int execute_HDR_set1_senderKID_test(CMP_HDR_TEST_FIXTURE *fixture)
{
ASN1_OCTET_STRING* senderKID = ASN1_OCTET_STRING_new();
if (!TEST_ptr(senderKID))
return 0;
ASN1_OCTET_STRING_set(senderKID, rand_data, sizeof(rand_data));
if (!TEST_int_eq(ossl_cmp_hdr_set1_senderKID(fixture->hdr, senderKID), 1))
return 0;
if (!TEST_int_eq(
ASN1_OCTET_STRING_cmp(fixture->hdr->senderKID, senderKID), 0))
return 0;
ASN1_OCTET_STRING_free(senderKID);
return 1;
}
static int test_HDR_set1_senderKID(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_set1_senderKID_test, tear_down);
return result;
}
static int execute_HDR_push0_freeText_test(CMP_HDR_TEST_FIXTURE *fixture)
{
ASN1_UTF8STRING* text = ASN1_UTF8STRING_new();
if (!TEST_ptr(text))
return 0;
if (!ASN1_STRING_set(text, "A free text", -1))
return 0;
if (!TEST_int_eq(
ossl_cmp_hdr_push0_freeText(fixture->hdr, text), 1))
return 0;
if (!TEST_true(text == sk_ASN1_UTF8STRING_value(
fixture->hdr->freeText, 0)))
return 0;
return 1;
}
static int test_HDR_push0_freeText(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_push0_freeText_test, tear_down);
return result;
}
static int execute_HDR_push1_freeText_test(CMP_HDR_TEST_FIXTURE *fixture)
{
ASN1_UTF8STRING* text = ASN1_UTF8STRING_new();
if (!TEST_ptr(text))
return 0;
if (!ASN1_STRING_set(text, "A free text", -1))
return 0;
if (!TEST_int_eq(
ossl_cmp_hdr_push1_freeText(fixture->hdr, text), 1))
return 0;
if (!TEST_int_eq(ASN1_STRING_cmp(
sk_ASN1_UTF8STRING_value(fixture->hdr->freeText, 0), text), 0))
return 0;
ASN1_UTF8STRING_free(text);
return 1;
}
static int test_HDR_push1_freeText(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_push1_freeText_test, tear_down);
return result;
}
static int
execute_HDR_generalInfo_push0_item_test(CMP_HDR_TEST_FIXTURE *fixture)
{
OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
if (!TEST_ptr(itav))
return 0;
if (!TEST_int_eq(
ossl_cmp_hdr_generalInfo_push0_item(fixture->hdr, itav), 1))
return 0;
if (!TEST_true(itav == sk_OSSL_CMP_ITAV_value(
fixture->hdr->generalInfo, 0)))
return 0;
return 1;
}
static int test_HDR_generalInfo_push0_item(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_generalInfo_push0_item_test, tear_down);
return result;
}
static int
execute_HDR_generalInfo_push1_items_test(CMP_HDR_TEST_FIXTURE *fixture)
{
const char oid[] = "1.2.3.4";
char buf[20];
OSSL_CMP_ITAV *itav;
STACK_OF(OSSL_CMP_ITAV) *itavs = NULL;
ASN1_INTEGER *asn1int = ASN1_INTEGER_new();
ASN1_TYPE *val = ASN1_TYPE_new();
if (!TEST_ptr(asn1int))
return 0;
if (!TEST_ptr(val))
return 0;
ASN1_INTEGER_set(asn1int, 88);
ASN1_TYPE_set(val, V_ASN1_INTEGER, asn1int);
itav = OSSL_CMP_ITAV_create(OBJ_txt2obj(oid, 1), val);
OSSL_CMP_ITAV_push0_stack_item(&itavs, itav);
if (!TEST_int_eq(
ossl_cmp_hdr_generalInfo_push1_items(fixture->hdr, itavs), 1))
return 0;
OBJ_obj2txt(buf, sizeof(buf), OSSL_CMP_ITAV_get0_type(
sk_OSSL_CMP_ITAV_value(fixture->hdr->generalInfo, 0)), 0);
if (!TEST_int_eq(memcmp(oid, buf, sizeof(oid)), 0))
return 0;
if (!TEST_int_eq(ASN1_TYPE_cmp(itav->infoValue.other,
OSSL_CMP_ITAV_get0_value(
sk_OSSL_CMP_ITAV_value(fixture->hdr->generalInfo, 0))), 0))
return 0;
sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
return 1;
}
static int test_HDR_generalInfo_push1_items(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 1;
EXECUTE_TEST(execute_HDR_generalInfo_push1_items_test, tear_down);
return result;
}
static int
execute_HDR_set_and_check_implicitConfirm_test(CMP_HDR_TEST_FIXTURE
* fixture)
{
return TEST_false(ossl_cmp_hdr_check_implicitConfirm(fixture->hdr))
&& TEST_true(ossl_cmp_hdr_set_implicitConfirm(fixture->hdr))
&& TEST_true(ossl_cmp_hdr_check_implicitConfirm(fixture->hdr));
}
static int test_HDR_set_and_check_implicit_confirm(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
EXECUTE_TEST(execute_HDR_set_and_check_implicitConfirm_test, tear_down);
return result;
}
static int execute_HDR_init_test(CMP_HDR_TEST_FIXTURE *fixture)
{
ASN1_OCTET_STRING *header_nonce = NULL;
ASN1_OCTET_STRING *ctx_nonce = NULL;
int res = 0;
if (!TEST_int_eq(fixture->expected,
ossl_cmp_hdr_init(fixture->cmp_ctx, fixture->hdr)))
goto err;
if (fixture->expected != 0) {
if (!TEST_int_eq(ossl_cmp_hdr_get_pvno(fixture->hdr), OSSL_CMP_PVNO)
|| !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(
OSSL_CMP_HDR_get0_transactionID(fixture->hdr),
fixture->cmp_ctx->transactionID)))
goto err;
header_nonce = OSSL_CMP_HDR_get0_recipNonce(fixture->hdr);
ctx_nonce = fixture->cmp_ctx->recipNonce;
if (ctx_nonce != NULL
&& (!TEST_ptr(header_nonce)
|| !TEST_int_eq(0, ASN1_OCTET_STRING_cmp(header_nonce,
ctx_nonce))))
goto err;
}
res = 1;
err:
return res;
}
static int test_HDR_init(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
unsigned char ref[CMP_TEST_REFVALUE_LENGTH];
fixture->expected = 1;
if (!TEST_int_eq(1, RAND_bytes(ref, sizeof(ref)))
|| !TEST_true(OSSL_CMP_CTX_set1_referenceValue(fixture->cmp_ctx,
ref, sizeof(ref)))) {
tear_down(fixture);
fixture = NULL;
}
EXECUTE_TEST(execute_HDR_init_test, tear_down);
return result;
}
static int test_HDR_init_with_subject(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
X509_NAME *subject = NULL;
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))) {
tear_down(fixture);
fixture = NULL;
}
X509_NAME_free(subject);
EXECUTE_TEST(execute_HDR_init_test, tear_down);
return result;
}
static int test_HDR_init_no_ref_no_subject(void)
{
SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
fixture->expected = 0;
EXECUTE_TEST(execute_HDR_init_test, tear_down);
return result;
}
void cleanup_tests(void)
{
return;
}
int setup_tests(void)
{
RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH);
/* Message header tests */
ADD_TEST(test_HDR_set_get_pvno);
ADD_TEST(test_HDR_get0_senderNonce);
ADD_TEST(test_HDR_set1_sender);
ADD_TEST(test_HDR_set1_recipient);
ADD_TEST(test_HDR_update_messageTime);
ADD_TEST(test_HDR_set1_senderKID);
ADD_TEST(test_HDR_push0_freeText);
/* indirectly tests ossl_cmp_pkifreetext_push_str(): */
ADD_TEST(test_HDR_push1_freeText);
ADD_TEST(test_HDR_generalInfo_push0_item);
ADD_TEST(test_HDR_generalInfo_push1_items);
ADD_TEST(test_HDR_set_and_check_implicit_confirm);
/* also tests public function OSSL_CMP_HDR_get0_transactionID(): */
/* also tests public function OSSL_CMP_HDR_get0_recipNonce(): */
/* also tests internal function ossl_cmp_hdr_get_pvno(): */
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. */
return 1;
}

111
test/cmp_status_test.c Normal file
View File

@ -0,0 +1,111 @@
/*
* 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"
typedef struct test_fixture {
const char *test_case_name;
int pkistatus;
const char *str; /* Not freed by tear_down */
const char *text; /* Not freed by tear_down */
int pkifailure;
} CMP_STATUS_TEST_FIXTURE;
static CMP_STATUS_TEST_FIXTURE *set_up(const char *const test_case_name)
{
CMP_STATUS_TEST_FIXTURE *fixture;
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
return NULL;
fixture->test_case_name = test_case_name;
return fixture;
}
static void tear_down(CMP_STATUS_TEST_FIXTURE *fixture)
{
OPENSSL_free(fixture);
}
/*
* Tests PKIStatusInfo creation and get-functions
*/
static int execute_PKISI_test(CMP_STATUS_TEST_FIXTURE *fixture)
{
OSSL_CMP_PKISI *si = NULL;
int status;
ASN1_UTF8STRING *statusString = NULL;
int res = 0, i;
if (!TEST_ptr(si = ossl_cmp_statusinfo_new(fixture->pkistatus,
fixture->pkifailure,
fixture->text)))
goto end;
status = ossl_cmp_pkisi_get_pkistatus(si);
if (!TEST_int_eq(fixture->pkistatus, status)
|| !TEST_str_eq(fixture->str, ossl_cmp_PKIStatus_to_string(status)))
goto end;
if (!TEST_ptr(statusString =
sk_ASN1_UTF8STRING_value(ossl_cmp_pkisi_get0_statusstring(si),
0))
|| !TEST_str_eq(fixture->text, (char *)statusString->data))
goto end;
if (!TEST_int_eq(fixture->pkifailure,
ossl_cmp_pkisi_get_pkifailureinfo(si)))
goto end;
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++)
if (!TEST_int_eq((fixture->pkifailure >> i) & 1,
ossl_cmp_pkisi_pkifailureinfo_check(si, i)))
goto end;
res = 1;
end:
OSSL_CMP_PKISI_free(si);
return res;
}
static int test_PKISI(void)
{
SETUP_TEST_FIXTURE(CMP_STATUS_TEST_FIXTURE, set_up);
fixture->pkistatus = OSSL_CMP_PKISTATUS_revocationNotification;
fixture->str = "PKIStatus: revocation notification - a revocation of the cert has occurred";
fixture->text = "this is an additional text describing the failure";
fixture->pkifailure = OSSL_CMP_CTX_FAILINFO_unsupportedVersion |
OSSL_CMP_CTX_FAILINFO_badDataFormat;
EXECUTE_TEST(execute_PKISI_test, tear_down);
return result;
}
void cleanup_tests(void)
{
return;
}
int setup_tests(void)
{
/*-
* this tests all of:
* ossl_cmp_statusinfo_new()
* ossl_cmp_pkisi_get_pkistatus()
* ossl_cmp_PKIStatus_to_string()
* ossl_cmp_pkisi_get0_statusstring()
* ossl_cmp_pkisi_get_pkifailureinfo()
* ossl_cmp_pkisi_pkifailureinfo_check()
*/
ADD_TEST(test_PKISI);
return 1;
}

View File

@ -0,0 +1,22 @@
#! /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_lib");
plan skip_all => "This test is not supported in a no-cmp build"
if disabled("cmp");
plan tests => 1;
ok(run(test(["cmp_hdr_test"])));

View File

@ -0,0 +1,22 @@
#! /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_lib");
plan skip_all => "This test is not supported in a no-cmp build"
if disabled("cmp");
plan tests => 1;
ok(run(test(["cmp_status_test"])));

View File

@ -4850,3 +4850,6 @@ EVP_KEYMGMT_number 4966 3_0_0 EXIST::FUNCTION:
EVP_KEYEXCH_number 4967 3_0_0 EXIST::FUNCTION:
EVP_KDF_number 4968 3_0_0 EXIST::FUNCTION:
EVP_SIGNATURE_number 4969 3_0_0 EXIST::FUNCTION:
OSSL_CMP_CTX_snprint_PKIStatus 4970 3_0_0 EXIST::FUNCTION:CMP
OSSL_CMP_HDR_get0_transactionID 4971 3_0_0 EXIST::FUNCTION:CMP
OSSL_CMP_HDR_get0_recipNonce 4972 3_0_0 EXIST::FUNCTION:CMP