mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
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:
parent
0a4d6c6748
commit
4dde554c6a
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
377
crypto/cmp/cmp_hdr.c
Normal 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;
|
||||
}
|
@ -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
302
crypto/cmp/cmp_status.c
Normal 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
127
doc/internal/man3/ossl_cmp_hdr_init.pod
Normal file
127
doc/internal/man3/ossl_cmp_hdr_init.pod
Normal 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
|
107
doc/internal/man3/ossl_cmp_statusinfo_new.pod
Normal file
107
doc/internal/man3/ossl_cmp_statusinfo_new.pod
Normal 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
|
46
doc/man3/OSSL_CMP_CTX_snprint_PKIStatus.pod
Normal file
46
doc/man3/OSSL_CMP_CTX_snprint_PKIStatus.pod
Normal 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
|
47
doc/man3/OSSL_CMP_HDR_get0_transactionID.pod
Normal file
47
doc/man3/OSSL_CMP_HDR_get0_transactionID.pod
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
468
test/cmp_hdr_test.c
Normal 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
111
test/cmp_status_test.c
Normal 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;
|
||||
}
|
22
test/recipes/65-test_cmp_hdr.t
Normal file
22
test/recipes/65-test_cmp_hdr.t
Normal 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"])));
|
22
test/recipes/65-test_cmp_status.t
Normal file
22
test/recipes/65-test_cmp_status.t
Normal 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"])));
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user