mirror of
https://github.com/openssl/openssl.git
synced 2025-01-26 20:03:32 +08:00
chunk 7 of CMP contribution to OpenSSL
add CMP message validation and related tests; while doing so: * add ERR_add_error_mem_bio() to crypto/err/err_prn.c * move ossl_cmp_add_error_txt() as ERR_add_error_txt() to crypto/err/err_prn.c * add X509_STORE_CTX_print_verify_cb() to crypto/x509/t_x509.c, adding internally x509_print_ex_brief(), print_certs(), and print_store_certs() * move {ossl_cmp_,}X509_STORE_get1_certs() to crypto/x509/x509_lu.c Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> (Merged from https://github.com/openssl/openssl/pull/10620)
This commit is contained in:
parent
235595c402
commit
31b28ad96a
@ -1,3 +1,3 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c
|
||||
|
@ -14,6 +14,8 @@
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED),
|
||||
"algorithm not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND),
|
||||
@ -50,6 +52,10 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"error protecting message"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH),
|
||||
"error setting certhash"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
|
||||
"error validating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
|
||||
"failed extracting pubkey"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM),
|
||||
"failure obtaining random"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE),
|
||||
@ -57,19 +63,38 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION),
|
||||
"missing key input for creating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE),
|
||||
"missing key usage digitalsignature"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY),
|
||||
"missing private key"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PROTECTION), "missing protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SENDER_IDENTIFICATION),
|
||||
"missing sender identification"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE),
|
||||
"missing trust store"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES),
|
||||
"multiple san sources"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_SUITABLE_SENDER_CERT),
|
||||
"no suitable sender cert"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NULL_ARGUMENT), "null argument"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKIBODY_ERROR), "pkibody error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND),
|
||||
"pkistatusinfo not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE),
|
||||
"potentially invalid certificate"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECIPNONCE_UNMATCHED),
|
||||
"recipnonce unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_NOT_ACCEPTED),
|
||||
"request not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED),
|
||||
"sender generalname type not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG),
|
||||
"srvcert does not validate msg"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED),
|
||||
"transactionid unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
|
||||
"unknown algorithm id"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
|
||||
@ -77,8 +102,11 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"unsupported algorithm"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
|
||||
"unsupported key type"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC),
|
||||
"unsupported protection alg dhbasedmac"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID),
|
||||
"wrong algorithm oid"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_PBM_VALUE), "wrong pbm value"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
@ -746,10 +746,8 @@ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
|
||||
const char *ossl_cmp_log_parse_metadata(const char *buf,
|
||||
OSSL_CMP_severity *level, char **func,
|
||||
char **file, int *line);
|
||||
/* workaround for 4096 bytes limitation of ERR_print_errors_cb() */
|
||||
void ossl_cmp_add_error_txt(const char *separator, const char *txt);
|
||||
# define ossl_cmp_add_error_data(txt) ossl_cmp_add_error_txt(" : ", txt)
|
||||
# define ossl_cmp_add_error_line(txt) ossl_cmp_add_error_txt("\n", txt)
|
||||
# define ossl_cmp_add_error_data(txt) ERR_add_error_txt(" : ", txt)
|
||||
# define ossl_cmp_add_error_line(txt) ERR_add_error_txt("\n", txt)
|
||||
/* functions manipulating lists of certificates etc could be generally useful */
|
||||
int ossl_cmp_sk_X509_add1_cert(STACK_OF(X509) *sk, X509 *cert,
|
||||
int no_dup, int prepend);
|
||||
@ -919,4 +917,12 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
|
||||
/* from cmp_vfy.c */
|
||||
typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *msg,
|
||||
int invalid_protection, int arg);
|
||||
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
|
||||
|
||||
#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */
|
||||
|
@ -142,100 +142,12 @@ int OSSL_CMP_print_to_bio(BIO *bio, const char *component, const char *file,
|
||||
level_string, msg) >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* auxiliary function for incrementally reporting texts via the error queue
|
||||
*/
|
||||
static void put_error(int lib, const char *func, int reason,
|
||||
const char *file, int line)
|
||||
{
|
||||
ERR_new();
|
||||
ERR_set_debug(file, line, func);
|
||||
ERR_set_error(lib, reason, NULL /* no data here, so fmt is NULL */);
|
||||
}
|
||||
|
||||
#define ERR_print_errors_cb_LIMIT 4096 /* size of char buf[] variable there */
|
||||
#define TYPICAL_MAX_OUTPUT_BEFORE_DATA 100
|
||||
#define MAX_DATA_LEN (ERR_print_errors_cb_LIMIT-TYPICAL_MAX_OUTPUT_BEFORE_DATA)
|
||||
void ossl_cmp_add_error_txt(const char *separator, const char *txt)
|
||||
{
|
||||
const char *file = NULL;
|
||||
int line;
|
||||
const char *func = NULL;
|
||||
const char *data = NULL;
|
||||
int flags;
|
||||
unsigned long err = ERR_peek_last_error();
|
||||
|
||||
if (separator == NULL)
|
||||
separator = "";
|
||||
if (err == 0)
|
||||
put_error(ERR_LIB_CMP, NULL, 0, "", 0);
|
||||
|
||||
do {
|
||||
size_t available_len, data_len;
|
||||
const char *curr = txt, *next = txt;
|
||||
char *tmp;
|
||||
|
||||
ERR_peek_last_error_all(&file, &line, &func, &data, &flags);
|
||||
if ((flags & ERR_TXT_STRING) == 0) {
|
||||
data = "";
|
||||
separator = "";
|
||||
}
|
||||
data_len = strlen(data);
|
||||
|
||||
/* workaround for limit of ERR_print_errors_cb() */
|
||||
if (data_len >= MAX_DATA_LEN
|
||||
|| strlen(separator) >= (size_t)(MAX_DATA_LEN - data_len))
|
||||
available_len = 0;
|
||||
else
|
||||
available_len = MAX_DATA_LEN - data_len - strlen(separator) - 1;
|
||||
/* MAX_DATA_LEN > available_len >= 0 */
|
||||
|
||||
if (separator[0] == '\0') {
|
||||
const size_t len_next = strlen(next);
|
||||
|
||||
if (len_next <= available_len) {
|
||||
next += len_next;
|
||||
curr = NULL; /* no need to split */
|
||||
}
|
||||
else {
|
||||
next += available_len;
|
||||
curr = next; /* will split at this point */
|
||||
}
|
||||
} else {
|
||||
while (*next != '\0' && (size_t)(next - txt) <= available_len) {
|
||||
curr = next;
|
||||
next = strstr(curr, separator);
|
||||
if (next != NULL)
|
||||
next += strlen(separator);
|
||||
else
|
||||
next = curr + strlen(curr);
|
||||
}
|
||||
if ((size_t)(next - txt) <= available_len)
|
||||
curr = NULL; /* the above loop implies *next == '\0' */
|
||||
}
|
||||
if (curr != NULL) {
|
||||
/* split error msg at curr since error data would get too long */
|
||||
if (curr != txt) {
|
||||
tmp = OPENSSL_strndup(txt, curr - txt);
|
||||
if (tmp == NULL)
|
||||
return;
|
||||
ERR_add_error_data(2, separator, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
put_error(ERR_LIB_CMP, func, err, file, line);
|
||||
txt = curr;
|
||||
} else {
|
||||
ERR_add_error_data(2, separator, txt);
|
||||
txt = next; /* finished */
|
||||
}
|
||||
} while (*txt != '\0');
|
||||
}
|
||||
|
||||
#define ERR_PRINT_BUF_SIZE 4096
|
||||
/* this is similar to ERR_print_errors_cb, but uses the CMP-specific cb type */
|
||||
void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn)
|
||||
{
|
||||
unsigned long err;
|
||||
char msg[ERR_print_errors_cb_LIMIT];
|
||||
char msg[ERR_PRINT_BUF_SIZE];
|
||||
const char *file = NULL, *func = NULL, *data = NULL;
|
||||
int line, flags;
|
||||
|
||||
@ -342,38 +254,6 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
|
||||
return 1;
|
||||
}
|
||||
|
||||
STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509) *sk;
|
||||
STACK_OF(X509_OBJECT) *objs;
|
||||
|
||||
if (store == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if ((sk = sk_X509_new_null()) == NULL)
|
||||
return NULL;
|
||||
objs = X509_STORE_get0_objects(store);
|
||||
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||
X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i));
|
||||
|
||||
if (cert != NULL) {
|
||||
if (!sk_X509_push(sk, cert))
|
||||
goto err;
|
||||
if (!X509_up_ref(cert)) {
|
||||
(void)sk_X509_pop(sk);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sk;
|
||||
|
||||
err:
|
||||
sk_X509_pop_free(sk, X509_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Builds up the certificate chain of certs as high up as possible using
|
||||
* the given list of certs containing all possible intermediate certificates and
|
||||
|
754
crypto/cmp/cmp_vfy.c
Normal file
754
crypto/cmp/cmp_vfy.c
Normal file
@ -0,0 +1,754 @@
|
||||
/*
|
||||
* Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2020
|
||||
* Copyright Siemens AG 2015-2020
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* CMP functions for PKIMessage checking */
|
||||
|
||||
#include "cmp_local.h"
|
||||
#include <openssl/cmp_util.h>
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/crmf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "crypto/x509.h"
|
||||
|
||||
/*
|
||||
* Verify a message protected by signature according to section 5.1.3.3
|
||||
* (sha1+RSA/DSA or any other algorithm supported by OpenSSL).
|
||||
*
|
||||
* Returns 1 on successful validation and 0 otherwise.
|
||||
*/
|
||||
static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
|
||||
const OSSL_CMP_MSG *msg, X509 *cert)
|
||||
{
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
CMP_PROTECTEDPART prot_part;
|
||||
int digest_nid, pk_nid;
|
||||
const EVP_MD *digest = NULL;
|
||||
EVP_PKEY *pubkey = NULL;
|
||||
int len;
|
||||
size_t prot_part_der_len = 0;
|
||||
unsigned char *prot_part_der = NULL;
|
||||
BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
|
||||
int res = 0;
|
||||
|
||||
if (!ossl_assert(cmp_ctx != NULL && msg != NULL && cert != NULL))
|
||||
return 0;
|
||||
|
||||
/* verify that keyUsage, if present, contains digitalSignature */
|
||||
if (!cmp_ctx->ignore_keyusage
|
||||
&& (X509_get_key_usage(cert) & X509v3_KU_DIGITAL_SIGNATURE) == 0) {
|
||||
CMPerr(0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE);
|
||||
goto sig_err;
|
||||
}
|
||||
|
||||
pubkey = X509_get_pubkey(cert);
|
||||
if (pubkey == NULL) {
|
||||
CMPerr(0, CMP_R_FAILED_EXTRACTING_PUBKEY);
|
||||
goto sig_err;
|
||||
}
|
||||
|
||||
/* create the DER representation of protected part */
|
||||
prot_part.header = msg->header;
|
||||
prot_part.body = msg->body;
|
||||
|
||||
len = i2d_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
|
||||
if (len < 0 || prot_part_der == NULL)
|
||||
goto end;
|
||||
prot_part_der_len = (size_t) len;
|
||||
|
||||
/* verify signature of protected part */
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(msg->header->protectionAlg->algorithm),
|
||||
&digest_nid, &pk_nid)
|
||||
|| digest_nid == NID_undef || pk_nid == NID_undef
|
||||
|| (digest = EVP_get_digestbynid(digest_nid)) == NULL) {
|
||||
CMPerr(0, CMP_R_ALGORITHM_NOT_SUPPORTED);
|
||||
goto sig_err;
|
||||
}
|
||||
|
||||
/* check msg->header->protectionAlg is consistent with public key type */
|
||||
if (EVP_PKEY_type(pk_nid) != EVP_PKEY_base_id(pubkey)) {
|
||||
CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
|
||||
goto sig_err;
|
||||
}
|
||||
if ((ctx = EVP_MD_CTX_new()) == NULL)
|
||||
goto end;
|
||||
if (EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pubkey)
|
||||
&& EVP_DigestVerify(ctx, msg->protection->data,
|
||||
msg->protection->length,
|
||||
prot_part_der, prot_part_der_len) == 1) {
|
||||
res = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sig_err:
|
||||
res = x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
if (res)
|
||||
ERR_add_error_mem_bio("\n", bio);
|
||||
res = 0;
|
||||
|
||||
end:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
OPENSSL_free(prot_part_der);
|
||||
EVP_PKEY_free(pubkey);
|
||||
BIO_free(bio);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Verify a message protected with PBMAC */
|
||||
static int verify_PBMAC(const OSSL_CMP_MSG *msg,
|
||||
const ASN1_OCTET_STRING *secret)
|
||||
{
|
||||
ASN1_BIT_STRING *protection = NULL;
|
||||
int valid = 0;
|
||||
|
||||
/* generate expected protection for the message */
|
||||
if ((protection = ossl_cmp_calc_protection(msg, secret, NULL)) == NULL)
|
||||
return 0; /* failed to generate protection string! */
|
||||
|
||||
valid = msg->protection != NULL && msg->protection->length >= 0
|
||||
&& msg->protection->type == protection->type
|
||||
&& msg->protection->length == protection->length
|
||||
&& CRYPTO_memcmp(msg->protection->data, protection->data,
|
||||
protection->length) == 0;
|
||||
ASN1_BIT_STRING_free(protection);
|
||||
if (!valid)
|
||||
CMPerr(0, CMP_R_WRONG_PBM_VALUE);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to validate certificate and path using any given store with trusted
|
||||
* certs (possibly including CRLs and a cert verification callback function)
|
||||
* and non-trusted intermediate certs from the given ctx.
|
||||
*
|
||||
* Returns 1 on successful validation and 0 otherwise.
|
||||
*/
|
||||
int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
X509 *cert)
|
||||
{
|
||||
int valid = 0;
|
||||
X509_STORE_CTX *csc = NULL;
|
||||
int err;
|
||||
|
||||
if (ctx == NULL || cert == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (trusted_store == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_TRUST_STORE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((csc = X509_STORE_CTX_new()) == NULL
|
||||
|| !X509_STORE_CTX_init(csc, trusted_store,
|
||||
cert, ctx->untrusted_certs))
|
||||
goto err;
|
||||
|
||||
valid = X509_verify_cert(csc) > 0;
|
||||
|
||||
/* make sure suitable error is queued even if callback did not do */
|
||||
err = ERR_peek_last_error();
|
||||
if (!valid && ERR_GET_REASON(err) != CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
|
||||
CMPerr(0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE);
|
||||
|
||||
err:
|
||||
X509_STORE_CTX_free(csc);
|
||||
return valid;
|
||||
}
|
||||
|
||||
/* Return 0 if expect_name != NULL and there is no matching actual_name */
|
||||
static int check_name(OSSL_CMP_CTX *ctx,
|
||||
const char *actual_desc, const X509_NAME *actual_name,
|
||||
const char *expect_desc, const X509_NAME *expect_name)
|
||||
{
|
||||
char *str;
|
||||
|
||||
if (expect_name == NULL)
|
||||
return 1; /* no expectation, thus trivially fulfilled */
|
||||
|
||||
/* make sure that a matching name is there */
|
||||
if (actual_name == NULL) {
|
||||
ossl_cmp_log1(WARN, ctx, "missing %s", actual_desc);
|
||||
return 0;
|
||||
}
|
||||
if (X509_NAME_cmp(actual_name, expect_name) == 0)
|
||||
return 1;
|
||||
|
||||
if ((str = X509_NAME_oneline(actual_name, NULL, 0)) != NULL)
|
||||
ossl_cmp_log2(INFO, ctx, " actual name in %s = %s", actual_desc, str);
|
||||
OPENSSL_free(str);
|
||||
if ((str = X509_NAME_oneline(expect_name, NULL, 0)) != NULL)
|
||||
ossl_cmp_log2(INFO, ctx, " does not match %s = %s", expect_desc, str);
|
||||
OPENSSL_free(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return 0 if skid != NULL and there is no matching subject key ID in cert */
|
||||
static int check_kid(OSSL_CMP_CTX *ctx,
|
||||
X509 *cert, const ASN1_OCTET_STRING *skid)
|
||||
{
|
||||
char *actual, *expect;
|
||||
const ASN1_OCTET_STRING *ckid = X509_get0_subject_key_id(cert);
|
||||
|
||||
if (skid == NULL)
|
||||
return 1; /* no expectation, thus trivially fulfilled */
|
||||
|
||||
/* make sure that the expected subject key identifier is there */
|
||||
if (ckid == NULL) {
|
||||
ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate");
|
||||
return 0;
|
||||
}
|
||||
if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0)
|
||||
return 1;
|
||||
|
||||
if ((actual = OPENSSL_buf2hexstr(ckid->data, ckid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", actual);
|
||||
if ((expect = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", expect);
|
||||
OPENSSL_free(expect);
|
||||
OPENSSL_free(actual);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = sk_X509_num(already_checked /* may be NULL */); i > 0; i--)
|
||||
if (X509_cmp(sk_X509_value(already_checked, i - 1), cert) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the given cert is acceptable as sender cert of the given message.
|
||||
* The subject DN must match, the subject key ID as well if present in the msg,
|
||||
* and the cert must be current (checked if ctx->trusted is not NULL).
|
||||
* Note that cert revocation etc. is checked by OSSL_CMP_validate_cert_path().
|
||||
*
|
||||
* Returns 0 on error or not acceptable, else 1.
|
||||
*/
|
||||
static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
const char *desc1, const char *desc2, X509 *cert,
|
||||
const STACK_OF(X509) *already_checked1,
|
||||
const STACK_OF(X509) *already_checked2,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509_STORE *ts = ctx->trusted;
|
||||
char *sub, *iss;
|
||||
X509_VERIFY_PARAM *vpm = ts != NULL ? X509_STORE_get0_param(ts) : NULL;
|
||||
int time_cmp;
|
||||
|
||||
ossl_cmp_log2(INFO, ctx, " considering %s %s with..", desc1, desc2);
|
||||
if ((sub = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subject = %s", sub);
|
||||
if ((iss = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " issuer = %s", iss);
|
||||
OPENSSL_free(iss);
|
||||
OPENSSL_free(sub);
|
||||
|
||||
if (already_checked(cert, already_checked1)
|
||||
|| already_checked(cert, already_checked2)) {
|
||||
ossl_cmp_info(ctx, " cert has already been checked");
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_cmp = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert),
|
||||
X509_get0_notAfter(cert));
|
||||
if (time_cmp != 0) {
|
||||
ossl_cmp_warn(ctx, time_cmp > 0 ? "cert has expired"
|
||||
: "cert is not yet valid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!check_name(ctx,
|
||||
"cert subject", X509_get_subject_name(cert),
|
||||
"sender field", msg->header->sender->d.directoryName))
|
||||
return 0;
|
||||
|
||||
if (!check_kid(ctx, cert, msg->header->senderKID))
|
||||
return 0;
|
||||
/* acceptable also if there is no senderKID in msg header */
|
||||
ossl_cmp_info(ctx, " cert is acceptable");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
X509 *scrt, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
if (!verify_signature(ctx, msg, scrt)) {
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
return 0;
|
||||
}
|
||||
if (!OSSL_CMP_validate_cert_path(ctx, store, scrt)) {
|
||||
ossl_cmp_warn(ctx, "cert path validation failed");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security
|
||||
* (NDS); Authentication Framework (AF)], only to use for IP and if the ctx
|
||||
* option is explicitly set: use self-issued certificates from extraCerts as
|
||||
* trust anchor to validate sender cert and msg -
|
||||
* provided it also can validate the newly enrolled certificate
|
||||
*/
|
||||
static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
int valid = 0;
|
||||
X509_STORE *store = X509_STORE_new();
|
||||
|
||||
if (store != NULL /* store does not include CRLs */
|
||||
&& ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts,
|
||||
1 /* self-issued only */))
|
||||
valid = check_msg_valid_cert(ctx, store, scrt, msg);
|
||||
if (valid) {
|
||||
/*
|
||||
* verify that the newly enrolled certificate (which is assumed to have
|
||||
* rid == 0) can also be validated with the same trusted store
|
||||
*/
|
||||
EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
OSSL_CMP_CERTRESPONSE *crep =
|
||||
ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip, 0);
|
||||
X509 *newcrt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
/*
|
||||
* maybe better use get_cert_status() from cmp_client.c, which catches
|
||||
* errors
|
||||
*/
|
||||
valid = OSSL_CMP_validate_cert_path(ctx, store, newcrt);
|
||||
X509_free(newcrt);
|
||||
}
|
||||
X509_STORE_free(store);
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try all certs in given list for verifying msg, normally or in 3GPP mode.
|
||||
* If already_checked1 == NULL then certs are assumed to be the msg->extraCerts.
|
||||
*/
|
||||
static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs,
|
||||
const char *desc,
|
||||
const STACK_OF(X509) *already_checked1,
|
||||
const STACK_OF(X509) *already_checked2,
|
||||
const OSSL_CMP_MSG *msg, int mode_3gpp)
|
||||
{
|
||||
int in_extraCerts = already_checked1 == NULL;
|
||||
int n_acceptable_certs = 0;
|
||||
int i;
|
||||
|
||||
if (sk_X509_num(certs) <= 0) {
|
||||
ossl_cmp_log1(WARN, ctx, "no %s", desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_X509_num(certs); i++) { /* certs may be NULL */
|
||||
X509 *cert = sk_X509_value(certs, i);
|
||||
|
||||
if (!ossl_assert(cert != NULL))
|
||||
return 0;
|
||||
if (!cert_acceptable(ctx, "cert from", desc, cert,
|
||||
already_checked1, already_checked2, msg))
|
||||
continue;
|
||||
n_acceptable_certs++;
|
||||
if (mode_3gpp ? check_msg_valid_cert_3gpp(ctx, cert, msg)
|
||||
: check_msg_valid_cert(ctx, ctx->trusted, cert, msg)) {
|
||||
/* store successful sender cert for further msgs in transaction */
|
||||
if (!X509_up_ref(cert))
|
||||
return 0;
|
||||
if (!ossl_cmp_ctx_set0_validatedSrvCert(ctx, cert)) {
|
||||
X509_free(cert);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (in_extraCerts && n_acceptable_certs == 0)
|
||||
ossl_cmp_warn(ctx, "no acceptable cert in extraCerts");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify msg trying first ctx->untrusted_certs, which should include extraCerts
|
||||
* at its front, then trying the trusted certs in truststore (if any) of ctx.
|
||||
*/
|
||||
static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
int mode_3gpp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ossl_cmp_info(ctx,
|
||||
mode_3gpp ? "failed; trying now 3GPP mode trusting extraCerts"
|
||||
: "trying first normal mode using trust store");
|
||||
if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts",
|
||||
NULL, NULL, msg, mode_3gpp))
|
||||
return 1;
|
||||
if (check_msg_with_certs(ctx, ctx->untrusted_certs, "untrusted certs",
|
||||
msg->extraCerts, NULL, msg, mode_3gpp))
|
||||
return 1;
|
||||
|
||||
if (ctx->trusted == NULL) {
|
||||
ossl_cmp_warn(ctx, mode_3gpp ? "no self-issued extraCerts"
|
||||
: "no trusted store");
|
||||
} else {
|
||||
STACK_OF(X509) *trusted = X509_STORE_get1_all_certs(ctx->trusted);
|
||||
ret = check_msg_with_certs(ctx, trusted,
|
||||
mode_3gpp ? "self-issued extraCerts"
|
||||
: "certs in trusted store",
|
||||
msg->extraCerts, ctx->untrusted_certs,
|
||||
msg, mode_3gpp);
|
||||
sk_X509_pop_free(trusted, X509_free);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* verify message signature with any acceptable and valid candidate cert */
|
||||
static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509 *scrt = ctx->validatedSrvCert; /* previous successful sender cert */
|
||||
GENERAL_NAME *sender = msg->header->sender;
|
||||
char *sname = NULL;
|
||||
char *skid_str = NULL;
|
||||
const ASN1_OCTET_STRING *skid = msg->header->senderKID;
|
||||
OSSL_cmp_log_cb_t backup_log_cb = ctx->log_cb;
|
||||
int res = 0;
|
||||
|
||||
if (sender == NULL || msg->body == NULL)
|
||||
return 0; /* other NULL cases already have been checked */
|
||||
if (sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* try first cached scrt, used successfully earlier in same transaction,
|
||||
* for validating this and any further msgs where extraCerts may be left out
|
||||
*/
|
||||
(void)ERR_set_mark();
|
||||
if (scrt != NULL
|
||||
&& cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, scrt, msg))) {
|
||||
(void)ERR_pop_to_mark();
|
||||
return 1;
|
||||
}
|
||||
(void)ERR_pop_to_mark();
|
||||
|
||||
/* release any cached sender cert that proved no more successfully usable */
|
||||
(void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = NULL; /* temporarily disable logging diagnostic info */
|
||||
|
||||
if (check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */)) {
|
||||
/* discard any diagnostic info on trying to use certs */
|
||||
ctx->log_cb = backup_log_cb; /* restore any logging */
|
||||
(void)ERR_pop_to_mark();
|
||||
res = 1;
|
||||
goto end;
|
||||
}
|
||||
/* failed finding a sender cert that verifies the message signature */
|
||||
ctx->log_cb = backup_log_cb; /* restore any logging */
|
||||
(void)ERR_clear_last_mark();
|
||||
|
||||
sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0);
|
||||
skid_str = skid == NULL ? NULL
|
||||
: OPENSSL_buf2hexstr(skid->data, skid->length);
|
||||
if (ctx->log_cb != NULL) {
|
||||
ossl_cmp_info(ctx, "verifying msg signature with valid cert that..");
|
||||
if (sname != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg sender name = %s", sname);
|
||||
if (skid_str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg senderKID = %s", skid_str);
|
||||
else
|
||||
ossl_cmp_info(ctx, "while msg header does not contain senderKID");
|
||||
/* re-do the above checks (just) for adding diagnostic information */
|
||||
check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */);
|
||||
check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
}
|
||||
|
||||
CMPerr(0, CMP_R_NO_SUITABLE_SENDER_CERT);
|
||||
if (sname != NULL) {
|
||||
ERR_add_error_txt(NULL, "for msg sender name = ");
|
||||
ERR_add_error_txt(NULL, sname);
|
||||
}
|
||||
if (skid_str != NULL) {
|
||||
ERR_add_error_txt(" and ", "for msg senderKID = ");
|
||||
ERR_add_error_txt(NULL, skid_str);
|
||||
}
|
||||
|
||||
end:
|
||||
OPENSSL_free(sname);
|
||||
OPENSSL_free(skid_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the protection of the given PKIMessage using either password-
|
||||
* based mac (PBM) or a signature algorithm. In the case of signature algorithm,
|
||||
* the sender certificate can have been pinned by providing it in ctx->srvCert,
|
||||
* else it is searched in msg->extraCerts, ctx->untrusted_certs, in ctx->trusted
|
||||
* (in this order) and is path is validated against ctx->trusted.
|
||||
*
|
||||
* If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg,
|
||||
* the trust anchor for validating the IP msg may be taken from msg->extraCerts
|
||||
* if a self-issued certificate is found there that can be used to
|
||||
* validate the enrolled certificate returned in the IP.
|
||||
* This is according to the need given in 3GPP TS 33.310.
|
||||
*
|
||||
* Returns 1 on success, 0 on error or validation failed.
|
||||
*/
|
||||
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509_ALGOR *alg;
|
||||
int nid = NID_undef, pk_nid = NID_undef;
|
||||
const ASN1_OBJECT *algorOID = NULL;
|
||||
X509 *scrt;
|
||||
|
||||
if (ctx == NULL || msg == NULL
|
||||
|| msg->header == NULL || msg->body == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((alg = msg->header->protectionAlg) == NULL /* unprotected message */
|
||||
|| msg->protection == NULL || msg->protection->data == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* determine the nid for the used protection algorithm */
|
||||
X509_ALGOR_get0(&algorOID, NULL, NULL, alg);
|
||||
nid = OBJ_obj2nid(algorOID);
|
||||
|
||||
switch (nid) {
|
||||
/* 5.1.3.1. Shared Secret Information */
|
||||
case NID_id_PasswordBasedMAC:
|
||||
if (verify_PBMAC(msg, ctx->secretValue)) {
|
||||
/*
|
||||
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
|
||||
* "shared secret information", then any certificate transported in
|
||||
* the caPubs field may be directly trusted as a root CA
|
||||
* certificate by the initiator.'
|
||||
*/
|
||||
switch (ossl_cmp_msg_get_bodytype(msg)) {
|
||||
case -1:
|
||||
return 0;
|
||||
case OSSL_CMP_PKIBODY_IP:
|
||||
case OSSL_CMP_PKIBODY_CP:
|
||||
case OSSL_CMP_PKIBODY_KUP:
|
||||
case OSSL_CMP_PKIBODY_CCP:
|
||||
if (ctx->trusted != NULL) {
|
||||
STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
|
||||
/* value.ip is same for cp, kup, and ccp */
|
||||
|
||||
if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
|
||||
/* adds both self-issued and not self-issued certs */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* 5.1.3.2 DH Key Pairs
|
||||
* Not yet supported
|
||||
*/
|
||||
case NID_id_DHBasedMac:
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC);
|
||||
break;
|
||||
|
||||
/*
|
||||
* 5.1.3.3. Signature
|
||||
*/
|
||||
default:
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), NULL, &pk_nid)
|
||||
|| pk_nid == NID_undef) {
|
||||
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
|
||||
break;
|
||||
}
|
||||
/* validate sender name of received msg */
|
||||
if (msg->header->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
break; /* FR#42: support for more than X509_NAME */
|
||||
}
|
||||
/*
|
||||
* Compare actual sender name of response with expected sender name.
|
||||
* Expected name can be set explicitly or the subject of ctx->srvCert.
|
||||
* Mitigates risk to accept misused certificate of an unauthorized
|
||||
* entity of a trusted hierarchy.
|
||||
*/
|
||||
if (!check_name(ctx, "sender DN field",
|
||||
msg->header->sender->d.directoryName,
|
||||
"expected sender", ctx->expected_sender))
|
||||
break;
|
||||
/* Note: if recipient was NULL-DN it could be learned here if needed */
|
||||
|
||||
scrt = ctx->srvCert;
|
||||
if (scrt == NULL) {
|
||||
if (check_msg_find_cert(ctx, msg))
|
||||
return 1;
|
||||
} else { /* use pinned sender cert */
|
||||
/* use ctx->srvCert for signature check even if not acceptable */
|
||||
if (verify_signature(ctx, msg, scrt))
|
||||
return 1;
|
||||
/* call cert_acceptable() for adding diagnostic information */
|
||||
(void)cert_acceptable(ctx, "explicitly set", "sender cert", scrt,
|
||||
NULL, NULL, msg);
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
CMPerr(0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* Check received message (i.e., response by server or request from client)
|
||||
* Any msg->extraCerts are prepended to ctx->untrusted_certs
|
||||
*
|
||||
* Ensures that:
|
||||
* it has a valid body type
|
||||
* its protection is valid or absent (allowed only if callback function is
|
||||
* present and function yields non-zero result using also supplied argument)
|
||||
* its transaction ID matches the previous transaction ID stored in ctx (if any)
|
||||
* its recipNonce matches the previous senderNonce stored in the ctx (if any)
|
||||
*
|
||||
* If everything is fine:
|
||||
* learns the senderNonce from the received message,
|
||||
* learns the transaction ID if it is not yet in ctx.
|
||||
*
|
||||
* returns body type (which is >= 0) of the message on success, -1 on error
|
||||
*/
|
||||
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg)
|
||||
{
|
||||
int rcvd_type;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && msg != NULL))
|
||||
return -1;
|
||||
|
||||
if (sk_X509_num(msg->extraCerts) > 10)
|
||||
ossl_cmp_warn(ctx,
|
||||
"received CMP message contains more than 10 extraCerts");
|
||||
|
||||
/* validate message protection */
|
||||
if (msg->header->protectionAlg != 0) {
|
||||
/* detect explicitly permitted exceptions for invalid protection */
|
||||
if (!OSSL_CMP_validate_msg(ctx, msg)
|
||||
&& (cb == NULL || !(*cb)(ctx, msg, 1, cb_arg))) {
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* detect explicitly permitted exceptions for missing protection */
|
||||
if (cb == NULL || !(*cb)(ctx, msg, 0, cb_arg)) {
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
|
||||
/* check CMP version number in header */
|
||||
if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compare received transactionID with the expected one in previous msg */
|
||||
if (ctx->transactionID != NULL
|
||||
&& (msg->header->transactionID == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->transactionID,
|
||||
msg->header->transactionID) != 0)) {
|
||||
CMPerr(0, CMP_R_TRANSACTIONID_UNMATCHED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compare received nonce with the one we sent */
|
||||
if (ctx->senderNonce != NULL
|
||||
&& (msg->header->recipNonce == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->senderNonce,
|
||||
msg->header->recipNonce) != 0)) {
|
||||
CMPerr(0, CMP_R_RECIPNONCE_UNMATCHED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 4210 section 5.1.1 states: the recipNonce is copied from
|
||||
* the senderNonce of the previous message in the transaction.
|
||||
* --> Store for setting in next message
|
||||
*/
|
||||
if (!ossl_cmp_ctx_set1_recipNonce(ctx, msg->header->senderNonce))
|
||||
return -1;
|
||||
|
||||
/* if not yet present, learn transactionID */
|
||||
if (ctx->transactionID == NULL
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, msg->header->transactionID))
|
||||
return -1;
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return -1;
|
||||
}
|
||||
return rcvd_type;
|
||||
}
|
||||
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
|
||||
{
|
||||
if (!ossl_assert(msg != NULL && msg->body != NULL))
|
||||
return 0;
|
||||
switch (msg->body->type) {
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
{
|
||||
X509_REQ *req = msg->body->value.p10cr;
|
||||
|
||||
if (X509_REQ_verify(req, X509_REQ_get0_pubkey(req)) > 0)
|
||||
return 1;
|
||||
CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED);
|
||||
return 0;
|
||||
}
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
return OSSL_CRMF_MSGS_verify_popo(msg->body->value.ir,
|
||||
OSSL_CMP_CERTREQID,
|
||||
accept_RAVerified);
|
||||
default:
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -17,12 +17,13 @@
|
||||
#include <openssl/err.h>
|
||||
#include "err_local.h"
|
||||
|
||||
#define ERR_PRINT_BUF_SIZE 4096
|
||||
void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
|
||||
void *u)
|
||||
{
|
||||
CRYPTO_THREAD_ID tid = CRYPTO_THREAD_get_current_id();
|
||||
unsigned long l;
|
||||
char buf[4096], *hex;
|
||||
char buf[ERR_PRINT_BUF_SIZE], *hex;
|
||||
const char *lib, *reason;
|
||||
const char *file, *data, *func;
|
||||
int line, flags;
|
||||
@ -44,6 +45,123 @@ void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
|
||||
}
|
||||
}
|
||||
|
||||
/* auxiliary function for incrementally reporting texts via the error queue */
|
||||
static void put_error(int lib, const char *func, int reason,
|
||||
const char *file, int line)
|
||||
{
|
||||
ERR_new();
|
||||
ERR_set_debug(file, line, func);
|
||||
ERR_set_error(lib, reason, NULL /* no data here, so fmt is NULL */);
|
||||
}
|
||||
|
||||
#define TYPICAL_MAX_OUTPUT_BEFORE_DATA 100
|
||||
#define MAX_DATA_LEN (ERR_PRINT_BUF_SIZE - TYPICAL_MAX_OUTPUT_BEFORE_DATA)
|
||||
void ERR_add_error_txt(const char *separator, const char *txt)
|
||||
{
|
||||
const char *file = NULL;
|
||||
int line;
|
||||
const char *func = NULL;
|
||||
const char *data = NULL;
|
||||
int flags;
|
||||
unsigned long err = ERR_peek_last_error();
|
||||
|
||||
if (separator == NULL)
|
||||
separator = "";
|
||||
if (err == 0)
|
||||
put_error(ERR_LIB_CMP, NULL, 0, "", 0);
|
||||
|
||||
do {
|
||||
size_t available_len, data_len;
|
||||
const char *curr = txt, *next = txt;
|
||||
const char *leading_separator = separator;
|
||||
int trailing_separator = 0;
|
||||
char *tmp;
|
||||
|
||||
ERR_peek_last_error_all(&file, &line, &func, &data, &flags);
|
||||
if ((flags & ERR_TXT_STRING) == 0) {
|
||||
data = "";
|
||||
leading_separator = "";
|
||||
}
|
||||
data_len = strlen(data);
|
||||
|
||||
/* workaround for limit of ERR_print_errors_cb() */
|
||||
if (data_len >= MAX_DATA_LEN
|
||||
|| strlen(separator) >= (size_t)(MAX_DATA_LEN - data_len))
|
||||
available_len = 0;
|
||||
else
|
||||
available_len = MAX_DATA_LEN - data_len - strlen(separator) - 1;
|
||||
/* MAX_DATA_LEN > available_len >= 0 */
|
||||
|
||||
if (*separator == '\0') {
|
||||
const size_t len_next = strlen(next);
|
||||
|
||||
if (len_next <= available_len) {
|
||||
next += len_next;
|
||||
curr = NULL; /* no need to split */
|
||||
} else {
|
||||
next += available_len;
|
||||
curr = next; /* will split at this point */
|
||||
}
|
||||
} else {
|
||||
while (*next != '\0' && (size_t)(next - txt) <= available_len) {
|
||||
curr = next;
|
||||
next = strstr(curr, separator);
|
||||
if (next != NULL) {
|
||||
next += strlen(separator);
|
||||
trailing_separator = *next == '\0';
|
||||
} else {
|
||||
next = curr + strlen(curr);
|
||||
}
|
||||
}
|
||||
if ((size_t)(next - txt) <= available_len)
|
||||
curr = NULL; /* the above loop implies *next == '\0' */
|
||||
}
|
||||
if (curr != NULL) {
|
||||
/* split error msg at curr since error data would get too long */
|
||||
if (curr != txt) {
|
||||
tmp = OPENSSL_strndup(txt, curr - txt);
|
||||
if (tmp == NULL)
|
||||
return;
|
||||
ERR_add_error_data(2, separator, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
put_error(ERR_LIB_CMP, func, err, file, line);
|
||||
txt = curr;
|
||||
} else {
|
||||
if (trailing_separator) {
|
||||
tmp = OPENSSL_strndup(txt, next - strlen(separator) - txt);
|
||||
if (tmp == NULL)
|
||||
return;
|
||||
/* output txt without the trailing separator */
|
||||
ERR_add_error_data(2, leading_separator, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
} else {
|
||||
ERR_add_error_data(2, leading_separator, txt);
|
||||
}
|
||||
txt = next; /* finished */
|
||||
}
|
||||
} while (*txt != '\0');
|
||||
}
|
||||
|
||||
void ERR_add_error_mem_bio(const char *separator, BIO *bio)
|
||||
{
|
||||
if (bio != NULL) {
|
||||
char *str;
|
||||
long len = BIO_get_mem_data(bio, &str);
|
||||
|
||||
if (len > 0) {
|
||||
if (str[len - 1] != '\0') {
|
||||
if (BIO_write(bio, "", 1) <= 0)
|
||||
return;
|
||||
|
||||
len = BIO_get_mem_data(bio, &str);
|
||||
}
|
||||
if (len > 1)
|
||||
ERR_add_error_txt(separator, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int print_bio(const char *str, size_t len, void *bp)
|
||||
{
|
||||
return BIO_write((BIO *)bp, str, len);
|
||||
|
@ -2067,6 +2067,7 @@ 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_ALGORITHM_NOT_SUPPORTED:139:algorithm not supported
|
||||
CMP_R_BAD_REQUEST_ID:108:bad request id
|
||||
CMP_R_CERTID_NOT_FOUND:109:certid not found
|
||||
CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found
|
||||
@ -2087,24 +2088,41 @@ CMP_R_ERROR_CREATING_RR:126:error creating rr
|
||||
CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus
|
||||
CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message
|
||||
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
|
||||
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
|
||||
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
|
||||
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
|
||||
CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range
|
||||
CMP_R_INVALID_ARGS:100:invalid args
|
||||
CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\
|
||||
missing key input for creating protection
|
||||
CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE:142:missing key usage digitalsignature
|
||||
CMP_R_MISSING_PRIVATE_KEY:131:missing private key
|
||||
CMP_R_MISSING_PROTECTION:143:missing protection
|
||||
CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification
|
||||
CMP_R_MISSING_TRUST_STORE:144:missing trust store
|
||||
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
|
||||
CMP_R_NO_STDIO:194:no stdio
|
||||
CMP_R_NO_SUITABLE_SENDER_CERT:145:no suitable sender cert
|
||||
CMP_R_NULL_ARGUMENT:103:null argument
|
||||
CMP_R_PKIBODY_ERROR:146:pkibody error
|
||||
CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found
|
||||
CMP_R_POTENTIALLY_INVALID_CERTIFICATE:139:potentially invalid certificate
|
||||
CMP_R_POTENTIALLY_INVALID_CERTIFICATE:147:potentially invalid certificate
|
||||
CMP_R_RECIPNONCE_UNMATCHED:148:recipnonce unmatched
|
||||
CMP_R_REQUEST_NOT_ACCEPTED:149:request not accepted
|
||||
CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED:150:\
|
||||
sender generalname type not supported
|
||||
CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG:151:srvcert does not validate msg
|
||||
CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
|
||||
CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
|
||||
CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
|
||||
CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
|
||||
CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
|
||||
CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
|
||||
CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
|
||||
CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\
|
||||
unsupported protection alg dhbasedmac
|
||||
CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid
|
||||
CMP_R_WRONG_PBM_VALUE:155:wrong pbm value
|
||||
CMS_R_ADD_SIGNER_ERROR:99:add signer error
|
||||
CMS_R_ATTRIBUTE_ERROR:161:attribute error
|
||||
CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present
|
||||
@ -3360,6 +3378,7 @@ X509_R_BAD_X509_FILETYPE:100:bad x509 filetype
|
||||
X509_R_BASE64_DECODE_ERROR:118:base64 decode error
|
||||
X509_R_CANT_CHECK_DH_KEY:114:cant check dh key
|
||||
X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
|
||||
X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed
|
||||
X509_R_CRL_ALREADY_DELTA:127:crl already delta
|
||||
X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
|
||||
X509_R_IDP_MISMATCH:128:idp mismatch
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/x509.h"
|
||||
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
int X509_print_fp(FILE *fp, X509 *x)
|
||||
@ -380,3 +381,107 @@ int X509_aux_print(BIO *out, X509 *x, int indent)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper functions for improving certificate verification error diagnostics
|
||||
*/
|
||||
|
||||
int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags)
|
||||
{
|
||||
unsigned long flags = ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE |
|
||||
XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN;
|
||||
|
||||
if (cert == NULL)
|
||||
return BIO_printf(bio, " (no certificate)\n") > 0;
|
||||
if (BIO_printf(bio, " certificate\n") <= 0
|
||||
|| !X509_print_ex(bio, cert, flags, ~X509_FLAG_NO_SUBJECT))
|
||||
return 0;
|
||||
if (X509_check_issued((X509 *)cert, cert) == X509_V_OK) {
|
||||
if (BIO_printf(bio, " self-issued\n") <= 0)
|
||||
return 0;
|
||||
} else {
|
||||
if (BIO_printf(bio, " ") <= 0
|
||||
|| !X509_print_ex(bio, cert, flags, ~X509_FLAG_NO_ISSUER))
|
||||
return 0;
|
||||
}
|
||||
if (!X509_print_ex(bio, cert, flags,
|
||||
~(X509_FLAG_NO_SERIAL | X509_FLAG_NO_VALIDITY)))
|
||||
return 0;
|
||||
if (X509_cmp_current_time(X509_get0_notBefore(cert)) > 0)
|
||||
if (BIO_printf(bio, " not yet valid\n") <= 0)
|
||||
return 0;
|
||||
if (X509_cmp_current_time(X509_get0_notAfter(cert)) < 0)
|
||||
if (BIO_printf(bio, " no more valid\n") <= 0)
|
||||
return 0;
|
||||
return X509_print_ex(bio, cert, flags, ~(neg_cflags));
|
||||
}
|
||||
|
||||
static int print_certs(BIO *bio, const STACK_OF(X509) *certs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (certs == NULL || sk_X509_num(certs) <= 0)
|
||||
return BIO_printf(bio, " (no certificates)\n") >= 0;
|
||||
|
||||
for (i = 0; i < sk_X509_num(certs); i++) {
|
||||
X509 *cert = sk_X509_value(certs, i);
|
||||
if (cert != NULL && !x509_print_ex_brief(bio, cert, 0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int print_store_certs(BIO *bio, X509_STORE *store)
|
||||
{
|
||||
if (store != NULL) {
|
||||
STACK_OF(X509) *certs = X509_STORE_get1_all_certs(store);
|
||||
int ret = print_certs(bio, certs);
|
||||
|
||||
sk_X509_pop_free(certs, X509_free);
|
||||
return ret;
|
||||
} else {
|
||||
return BIO_printf(bio, " (no trusted store)\n") >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extend the error queue with details on a failed cert verification */
|
||||
int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
if (ok == 0 && ctx != NULL) {
|
||||
int cert_error = X509_STORE_CTX_get_error(ctx);
|
||||
int depth = X509_STORE_CTX_get_error_depth(ctx);
|
||||
X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
|
||||
|
||||
BIO_printf(bio, "%s at depth=%d error=%d (%s)\n",
|
||||
X509_STORE_CTX_get0_parent_ctx(ctx) != NULL
|
||||
? "CRL path validation" : "certificate verification",
|
||||
depth, cert_error,
|
||||
X509_verify_cert_error_string(cert_error));
|
||||
BIO_printf(bio, "failure for:\n");
|
||||
x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
|
||||
if (cert_error == X509_V_ERR_CERT_UNTRUSTED
|
||||
|| cert_error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
|
||||
|| cert_error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
|
||||
|| cert_error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
|
||||
|| cert_error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
|
||||
|| cert_error == X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
|
||||
|| cert_error == X509_V_ERR_STORE_LOOKUP) {
|
||||
BIO_printf(bio, "non-trusted certs:\n");
|
||||
print_certs(bio, X509_STORE_CTX_get0_untrusted(ctx));
|
||||
BIO_printf(bio, "certs in trust store:\n");
|
||||
print_store_certs(bio, X509_STORE_CTX_get0_store(ctx));
|
||||
}
|
||||
CMPerr(0, X509_R_CERTIFICATE_VERIFICATION_FAILED);
|
||||
ERR_add_error_mem_bio("\n", bio);
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO we could check policies here too, e.g.:
|
||||
* if (cert_error == X509_V_OK && ok == 2)
|
||||
* policies_print(NULL, ctx);
|
||||
*/
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
|
||||
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE),
|
||||
"cert already in hash table"},
|
||||
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CERTIFICATE_VERIFICATION_FAILED),
|
||||
"certificate verification failed"},
|
||||
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"},
|
||||
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
|
||||
"crl verify failure"},
|
||||
|
@ -532,6 +532,41 @@ STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v)
|
||||
return v->objs;
|
||||
}
|
||||
|
||||
STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store)
|
||||
{
|
||||
STACK_OF(X509) *sk;
|
||||
STACK_OF(X509_OBJECT) *objs;
|
||||
int i;
|
||||
|
||||
if (store == NULL) {
|
||||
X509err(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if ((sk = sk_X509_new_null()) == NULL)
|
||||
return NULL;
|
||||
X509_STORE_lock(store);
|
||||
objs = X509_STORE_get0_objects(store);
|
||||
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||
X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i));
|
||||
|
||||
if (cert != NULL) {
|
||||
if (!X509_up_ref(cert))
|
||||
goto err;
|
||||
if (!sk_X509_push(sk, cert)) {
|
||||
X509_free(cert);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
X509_STORE_unlock(store);
|
||||
return sk;
|
||||
|
||||
err:
|
||||
X509_STORE_unlock(store);
|
||||
sk_X509_pop_free(sk, X509_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
|
||||
{
|
||||
int i, idx, cnt;
|
||||
|
@ -14,7 +14,6 @@ ossl_cmp_log2,
|
||||
ossl_cmp_log3,
|
||||
ossl_cmp_log4,
|
||||
ossl_cmp_log_parse_metadata,
|
||||
ossl_cmp_add_error_txt,
|
||||
ossl_cmp_add_error_data,
|
||||
ossl_cmp_add_error_line
|
||||
- logging and error reporting support for CMP
|
||||
@ -40,7 +39,6 @@ ossl_cmp_add_error_line
|
||||
OSSL_CMP_severity *level, char **func,
|
||||
char **file, int *line);
|
||||
|
||||
void ossl_cmp_add_error_txt(const char *separator, const char *txt);
|
||||
#define ossl_cmp_add_error_data(txt)
|
||||
#define ossl_cmp_add_error_line(txt)
|
||||
|
||||
@ -72,17 +70,11 @@ the variable pointed to by I<file> with the filename string or NULL, and
|
||||
the variable pointed to by I<line> with the line number or -1.
|
||||
Any string returned via I<*func> and I<*file> must be freeed by the caller.
|
||||
|
||||
ossl_cmp_add_error_txt() appends text to the extra data field of the last
|
||||
error message in the OpenSSL error queue, after adding the optional separator
|
||||
unless data has been empty so far. The text can be of arbitrary length,
|
||||
which is not possible when using L<ERR_add_error_data(3)> in conjunction with
|
||||
L<ERR_print_errors_cb(3)>.
|
||||
|
||||
ossl_cmp_add_error_data() is a macro calling
|
||||
ossl_cmp_add_error_txt() with the separator being ":".
|
||||
L<ERR_add_error_txt(3)> with the separator being ":".
|
||||
|
||||
ossl_cmp_add_error_line() is a macro calling
|
||||
ossl_cmp_add_error_txt() with the separator being "\n".
|
||||
L<ERR_add_error_txt(3)> with the separator being "\n".
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
@ -90,13 +82,16 @@ ossl_cmp_log_parse_metadata() returns the pointer to the actual message text
|
||||
after the OSSL_CMP_LOG_PREFIX and level and ':' if found in the buffer,
|
||||
else the beginning of the buffer.
|
||||
|
||||
ossl_cmp_add_error_txt()
|
||||
ossl_cmp_add_error_data(), and
|
||||
ossl_cmp_add_error_data() and
|
||||
ossl_cmp_add_error_line()
|
||||
do not return anything.
|
||||
|
||||
All other functions return 1 on success, 0 on error.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<ERR_add_error_txt(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The OpenSSL CMP support was added in OpenSSL 3.0.
|
||||
|
@ -3,7 +3,8 @@
|
||||
=head1 NAME
|
||||
|
||||
ERR_raise, ERR_raise_data,
|
||||
ERR_put_error, ERR_add_error_data, ERR_add_error_vdata
|
||||
ERR_put_error, ERR_add_error_data, ERR_add_error_vdata,
|
||||
ERR_add_error_txt, ERR_add_error_mem_bio
|
||||
- record an error
|
||||
|
||||
=head1 SYNOPSIS
|
||||
@ -15,6 +16,8 @@ ERR_put_error, ERR_add_error_data, ERR_add_error_vdata
|
||||
|
||||
void ERR_add_error_data(int num, ...);
|
||||
void ERR_add_error_vdata(int num, va_list arg);
|
||||
void ERR_add_error_txt(const char *sep, const char *txt);
|
||||
void ERR_add_error_mem_bio(const char *sep, BIO *bio);
|
||||
|
||||
Deprecated since OpenSSL 3.0:
|
||||
|
||||
@ -38,9 +41,23 @@ B<func> of library B<lib>, in line number B<line> of B<file>.
|
||||
This function is usually called by a macro.
|
||||
|
||||
ERR_add_error_data() associates the concatenation of its B<num> string
|
||||
arguments with the error code added last.
|
||||
arguments as additional data with the error code added last.
|
||||
ERR_add_error_vdata() is similar except the argument is a B<va_list>.
|
||||
Multiple calls to these functions append to the current top of the error queue.
|
||||
The total length of the string data per error is limited to 4096 characters.
|
||||
|
||||
ERR_add_error_txt() appends the given text string as additional data to the
|
||||
last error queue entry, after inserting the optional separator string if it is
|
||||
not NULL and the top error entry does not yet have additional data.
|
||||
In case the separator is at the end of the text it is not appended to the data.
|
||||
The B<sep> argument may be for instance "\n" to insert a line break when needed.
|
||||
If the associated data would become more than 4096 characters long
|
||||
(which is the limit given above)
|
||||
it is split over sufficiently many new copies of the last error queue entry.
|
||||
|
||||
ERR_add_error_mem_bio() is the same as ERR_add_error_txt() except that
|
||||
the text string is taken from the given memory BIO.
|
||||
It appends '\0' to the BIO contents if not already NUL-terminated.
|
||||
|
||||
L<ERR_load_strings(3)> can be used to register
|
||||
error strings so that the application can a generate human-readable
|
||||
@ -76,8 +93,10 @@ the ASN1err() macro.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
ERR_raise(), ERR_put_error(), ERR_add_error_data() and
|
||||
ERR_add_error_vdata() return no values.
|
||||
ERR_raise(), ERR_put_error(),
|
||||
ERR_add_error_data(), ERR_add_error_vdata()
|
||||
ERR_add_error_txt(), and ERR_add_error_mem_bio()
|
||||
return no values.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
@ -87,6 +106,10 @@ ERR_raise() and ERR_put_error() are implemented as macros.
|
||||
|
||||
L<ERR_load_strings(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
B<ERR_add_error_txt> and B<ERR_add_error_mem_bio> were added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
86
doc/man3/OSSL_CMP_validate_msg.pod
Normal file
86
doc/man3/OSSL_CMP_validate_msg.pod
Normal file
@ -0,0 +1,86 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
OSSL_CMP_validate_msg,
|
||||
OSSL_CMP_validate_cert_path
|
||||
- functions for verifying CMP message protection
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cmp.h>
|
||||
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
|
||||
X509_STORE *trusted_store, X509 *cert);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is the API for validating the protection of CMP messages,
|
||||
which includes validating CMP message sender certificates and their paths
|
||||
while optionally checking the revocation status of the certificates(s).
|
||||
|
||||
OSSL_CMP_validate_msg() validates the protection of the given C<msg>
|
||||
using either password-based mac (PBM) or a signature algorithm.
|
||||
|
||||
In case of signature algorithm, the certificate to use for the signature check
|
||||
is preferably the one provided by a call to L<OSSL_CMP_CTX_set1_srvCert(3)>.
|
||||
If no such sender cert has been pinned then candidate sender certificates are
|
||||
taken from the list of certificates received in the C<msg> extraCerts, then any
|
||||
certificates provided before via L<OSSL_CMP_CTX_set1_untrusted_certs(3)>, and
|
||||
then all trusted certificates provided via L<OSSL_CMP_CTX_set0_trustedStore(3)>,
|
||||
where a candidate is acceptable only if has not expired, its subject DN matches
|
||||
the C<msg> sender DN (as far as present), and its subject key identifier
|
||||
is present and matches the senderKID (as far as the latter present).
|
||||
Each acceptable cert is tried in the given order to see if the message
|
||||
signature check succeeds and the cert and its path can be verified
|
||||
using any trust store set via L<OSSL_CMP_CTX_set0_trustedStore(3)>.
|
||||
|
||||
If the option OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR was set by calling
|
||||
L<OSSL_CMP_CTX_set_option(3)>, for an Initialization Response (IP) message
|
||||
any self-issued certificate from the C<msg> extraCerts field may also be used
|
||||
as trust anchor for the path verification of an acceptable cert if it can be
|
||||
used also to validate the issued certificate returned in the IP message. This is
|
||||
according to TS 33.310 [Network Domain Security (NDS); Authentication Framework
|
||||
(AF)] document specified by the The 3rd Generation Partnership Project (3GPP).
|
||||
|
||||
Any cert that has been found as described above is cached and tried first when
|
||||
validating the signatures of subsequent messages in the same transaction.
|
||||
|
||||
After successful validation of PBM-based protection of a certificate response
|
||||
the certificates in the caPubs field (if any) are added to the trusted
|
||||
certificates provided via L<OSSL_CMP_CTX_set0_trustedStore(3)>, such that
|
||||
they are available for validating subsequent messages in the same context.
|
||||
Those could apply to any Polling Response (pollRep), error, or PKI Confirmation
|
||||
(PKIConf) messages following in the same or future transactions.
|
||||
|
||||
OSSL_CMP_validate_cert_path() attempts to validate the given certificate and its
|
||||
path using the given store of trusted certs (possibly including CRLs and a cert
|
||||
verification callback) and non-trusted intermediate certs from the B<ctx>.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
CMP is defined in RFC 4210 (and CRMF in RFC 4211).
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_CMP_validate_msg() and OSSL_CMP_validate_cert_path()
|
||||
return 1 on success, 0 on error or validation failed.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<OSSL_CMP_CTX_new(3)>, L<OSSL_CMP_exec_IR_ses(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
|
@ -14,14 +14,16 @@ X509_STORE_CTX_get_check_issued,
|
||||
X509_STORE_CTX_get_get_issuer,
|
||||
X509_STORE_CTX_get_verify_cb,
|
||||
X509_STORE_CTX_set_verify_cb,
|
||||
X509_STORE_CTX_verify_cb
|
||||
- get and set verification callback
|
||||
X509_STORE_CTX_verify_cb,
|
||||
X509_STORE_CTX_print_verify_cb
|
||||
- get and set X509_STORE_CTX components such as verification callback
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *);
|
||||
int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx);
|
||||
|
||||
@ -63,6 +65,12 @@ structure and receive additional information about the error, for example
|
||||
by calling X509_STORE_CTX_get_current_cert(). Additional application data can
|
||||
be passed to the callback via the B<ex_data> mechanism.
|
||||
|
||||
X509_STORE_CTX_print_verify_cb() is a verification callback function that,
|
||||
when a certificate verification has failed, adds an entry to the error queue
|
||||
with code B<X509_R_CERTIFICATE_VERIFICATION_FAILED> and with diagnostic details,
|
||||
including the most relevant fields of the target certificate that failed to
|
||||
verify and, if appropriate, of the available untrusted and trusted certificates.
|
||||
|
||||
X509_STORE_CTX_get_verify_cb() returns the value of the current callback
|
||||
for the specific B<ctx>.
|
||||
|
||||
@ -200,6 +208,8 @@ X509_STORE_CTX_get_cert_crl(), X509_STORE_CTX_get_check_policy(),
|
||||
X509_STORE_CTX_get_lookup_certs(), X509_STORE_CTX_get_lookup_crls()
|
||||
and X509_STORE_CTX_get_cleanup() functions were added in OpenSSL 1.1.0.
|
||||
|
||||
X509_STORE_CTX_print_verify_cb() was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
@ -3,7 +3,8 @@
|
||||
=head1 NAME
|
||||
|
||||
X509_STORE_get0_param, X509_STORE_set1_param,
|
||||
X509_STORE_get0_objects - X509_STORE setter and getter functions
|
||||
X509_STORE_get0_objects, X509_STORE_get1_all_certs
|
||||
- X509_STORE setter and getter functions
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@ -12,6 +13,7 @@ X509_STORE_get0_objects - X509_STORE setter and getter functions
|
||||
X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx);
|
||||
int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
|
||||
STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *ctx);
|
||||
STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *st);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@ -22,10 +24,12 @@ X509_STORE_get0_param() retrieves an internal pointer to the verification
|
||||
parameters for B<ctx>. The returned pointer must not be freed by the
|
||||
calling application
|
||||
|
||||
X509_STORE_get0_objects() retrieve an internal pointer to the store's
|
||||
X509_STORE_get0_objects() retrieves an internal pointer to the store's
|
||||
X509 object cache. The cache contains B<X509> and B<X509_CRL> objects. The
|
||||
returned pointer must not be freed by the calling application.
|
||||
|
||||
X509_STORE_get1_all_certs() returns a list of all certificates in the store.
|
||||
The caller is responsible for freeing the returned list.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
@ -36,6 +40,9 @@ X509_STORE_set1_param() returns 1 for success and 0 for failure.
|
||||
|
||||
X509_STORE_get0_objects() returns a pointer to a stack of B<X509_OBJECT>.
|
||||
|
||||
X509_STORE_get1_all_certs() returns a pointer to a stack of the retrieved
|
||||
certificates on success, else NULL.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<X509_STORE_new(3)>
|
||||
@ -44,6 +51,7 @@ L<X509_STORE_new(3)>
|
||||
|
||||
B<X509_STORE_get0_param> and B<X509_STORE_get0_objects> were added in
|
||||
OpenSSL 1.1.0.
|
||||
B<X509_STORE_get1_certs> was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
|
@ -288,5 +288,6 @@ struct x509_object_st {
|
||||
|
||||
int a2i_ipadd(unsigned char *ipout, const char *ipasc);
|
||||
int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
|
||||
int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags);
|
||||
|
||||
void x509_init_sig_info(X509 *x);
|
||||
|
@ -348,6 +348,11 @@ ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
/* support application-level CMP debugging in cmp.c: */
|
||||
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
|
||||
|
||||
/* from cmp_vfy.c */
|
||||
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx,
|
||||
X509_STORE *trusted_store, X509 *cert);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
@ -33,6 +33,7 @@ int ERR_load_CMP_strings(void);
|
||||
/*
|
||||
* CMP reason codes.
|
||||
*/
|
||||
# define CMP_R_ALGORITHM_NOT_SUPPORTED 139
|
||||
# define CMP_R_BAD_REQUEST_ID 108
|
||||
# define CMP_R_CERTID_NOT_FOUND 109
|
||||
# define CMP_R_CERTIFICATE_NOT_FOUND 112
|
||||
@ -53,23 +54,38 @@ int ERR_load_CMP_strings(void);
|
||||
# define CMP_R_ERROR_PARSING_PKISTATUS 107
|
||||
# define CMP_R_ERROR_PROTECTING_MESSAGE 127
|
||||
# define CMP_R_ERROR_SETTING_CERTHASH 128
|
||||
# define CMP_R_ERROR_VALIDATING_PROTECTION 140
|
||||
# define CMP_R_FAILED_EXTRACTING_PUBKEY 141
|
||||
# define CMP_R_FAILURE_OBTAINING_RANDOM 110
|
||||
# define CMP_R_FAIL_INFO_OUT_OF_RANGE 129
|
||||
# define CMP_R_INVALID_ARGS 100
|
||||
# define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130
|
||||
# define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE 142
|
||||
# define CMP_R_MISSING_PRIVATE_KEY 131
|
||||
# define CMP_R_MISSING_PROTECTION 143
|
||||
# define CMP_R_MISSING_SENDER_IDENTIFICATION 111
|
||||
# define CMP_R_MISSING_TRUST_STORE 144
|
||||
# define CMP_R_MULTIPLE_SAN_SOURCES 102
|
||||
# define CMP_R_NO_STDIO 194
|
||||
# define CMP_R_NO_SUITABLE_SENDER_CERT 145
|
||||
# define CMP_R_NULL_ARGUMENT 103
|
||||
# define CMP_R_PKIBODY_ERROR 146
|
||||
# define CMP_R_PKISTATUSINFO_NOT_FOUND 132
|
||||
# define CMP_R_POTENTIALLY_INVALID_CERTIFICATE 139
|
||||
# define CMP_R_POTENTIALLY_INVALID_CERTIFICATE 147
|
||||
# define CMP_R_RECIPNONCE_UNMATCHED 148
|
||||
# define CMP_R_REQUEST_NOT_ACCEPTED 149
|
||||
# define CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED 150
|
||||
# define CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG 151
|
||||
# define CMP_R_TRANSACTIONID_UNMATCHED 152
|
||||
# define CMP_R_UNEXPECTED_PKIBODY 133
|
||||
# define CMP_R_UNEXPECTED_PVNO 153
|
||||
# define CMP_R_UNKNOWN_ALGORITHM_ID 134
|
||||
# define CMP_R_UNKNOWN_CERT_TYPE 135
|
||||
# define CMP_R_UNSUPPORTED_ALGORITHM 136
|
||||
# define CMP_R_UNSUPPORTED_KEY_TYPE 137
|
||||
# define CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC 154
|
||||
# define CMP_R_WRONG_ALGORITHM_OID 138
|
||||
# define CMP_R_WRONG_PBM_VALUE 155
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
@ -333,6 +333,8 @@ void ERR_print_errors(BIO *bp);
|
||||
|
||||
void ERR_add_error_data(int num, ...);
|
||||
void ERR_add_error_vdata(int num, va_list args);
|
||||
void ERR_add_error_txt(const char *sepr, const char *txt);
|
||||
void ERR_add_error_mem_bio(const char *sep, BIO *bio);
|
||||
|
||||
int ERR_load_strings(int lib, ERR_STRING_DATA *str);
|
||||
int ERR_load_strings_const(const ERR_STRING_DATA *str);
|
||||
|
@ -67,6 +67,7 @@ DEFINE_STACK_OF(X509_VERIFY_PARAM)
|
||||
int X509_STORE_set_depth(X509_STORE *store, int depth);
|
||||
|
||||
typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *);
|
||||
int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx);
|
||||
typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *);
|
||||
typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer,
|
||||
X509_STORE_CTX *ctx, X509 *x);
|
||||
@ -287,8 +288,9 @@ void X509_STORE_free(X509_STORE *v);
|
||||
int X509_STORE_lock(X509_STORE *ctx);
|
||||
int X509_STORE_unlock(X509_STORE *ctx);
|
||||
int X509_STORE_up_ref(X509_STORE *v);
|
||||
STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v);
|
||||
|
||||
STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v);
|
||||
STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *st);
|
||||
STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
|
||||
STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
|
||||
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
|
||||
|
@ -107,6 +107,7 @@ int ERR_load_X509_strings(void);
|
||||
# define X509_R_BASE64_DECODE_ERROR 118
|
||||
# define X509_R_CANT_CHECK_DH_KEY 114
|
||||
# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
|
||||
# define X509_R_CERTIFICATE_VERIFICATION_FAILED 139
|
||||
# define X509_R_CRL_ALREADY_DELTA 127
|
||||
# define X509_R_CRL_VERIFY_FAILURE 131
|
||||
# define X509_R_IDP_MISMATCH 128
|
||||
|
@ -455,7 +455,7 @@ IF[{- !$disabled{tests} -}]
|
||||
|
||||
IF[{- !$disabled{cmp} -}]
|
||||
PROGRAMS{noinst}=cmp_asn_test cmp_ctx_test cmp_status_test cmp_hdr_test \
|
||||
cmp_protect_test cmp_msg_test
|
||||
cmp_protect_test cmp_msg_test cmp_vfy_test
|
||||
ENDIF
|
||||
|
||||
SOURCE[cmp_asn_test]=cmp_asn_test.c cmp_testlib.c
|
||||
@ -482,6 +482,10 @@ IF[{- !$disabled{tests} -}]
|
||||
INCLUDE[cmp_msg_test]=.. ../include ../apps/include
|
||||
DEPEND[cmp_msg_test]=../libcrypto.a libtestutil.a
|
||||
|
||||
SOURCE[cmp_vfy_test]=cmp_status_test.c cmp_testlib.c
|
||||
INCLUDE[cmp_vfy_test]=.. ../include ../apps/include
|
||||
DEPEND[cmp_vfy_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
|
||||
|
@ -169,7 +169,7 @@ static int execute_CTX_print_errors_test(OSSL_CMP_CTX_TEST_FIXTURE *fixture)
|
||||
base_err_msg_size = strlen("INVALID_ARGS") + strlen(" : ");
|
||||
expected_size = base_err_msg_size;
|
||||
while (expected_size < 4096) { /* force split */
|
||||
ossl_cmp_add_error_txt(STR_SEP, max_str_literal);
|
||||
ERR_add_error_txt(STR_SEP, max_str_literal);
|
||||
expected_size += strlen(STR_SEP) + strlen(max_str_literal);
|
||||
}
|
||||
expected_size += base_err_msg_size - 2 * strlen(STR_SEP);
|
||||
@ -794,8 +794,7 @@ int setup_tests(void)
|
||||
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
|
||||
/*
|
||||
* also tests OSSL_CMP_CTX_set_log_cb(), OSSL_CMP_print_errors_cb(),
|
||||
* ossl_cmp_add_error_txt(), and the macros
|
||||
* ossl_cmp_add_error_data and ossl_cmp_add_error_line:
|
||||
* and the macros ossl_cmp_add_error_data and ossl_cmp_add_error_line:
|
||||
*/
|
||||
ADD_TEST(test_CTX_print_errors);
|
||||
#endif
|
||||
|
@ -387,7 +387,7 @@ static int execute_X509_STORE_test(CMP_PROTECT_TEST_FIXTURE *fixture)
|
||||
fixture->certs,
|
||||
fixture->callback_arg)))
|
||||
goto err;
|
||||
sk = ossl_cmp_X509_STORE_get1_certs(store);
|
||||
sk = X509_STORE_get1_all_certs(store);
|
||||
if (!TEST_int_eq(0, STACK_OF_X509_cmp(sk, fixture->chain)))
|
||||
goto err;
|
||||
res = 1;
|
||||
|
636
test/cmp_vfy_test.c
Normal file
636
test/cmp_vfy_test.c
Normal file
@ -0,0 +1,636 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "../crypto/crmf/crmf_local.h" /* for manipulating POPO signature */
|
||||
|
||||
static const char *server_f;
|
||||
static const char *client_f;
|
||||
static const char *endentity1_f;
|
||||
static const char *endentity2_f;
|
||||
static const char *root_f;
|
||||
static const char *intermediate_f;
|
||||
static const char *ir_protected_f;
|
||||
static const char *ir_unprotected_f;
|
||||
static const char *ir_rmprotection_f;
|
||||
static const char *ip_waiting_f;
|
||||
static const char *instacert_f;
|
||||
static const char *instaca_f;
|
||||
static const char *ir_protected_0_extracerts;
|
||||
static const char *ir_protected_2_extracerts;
|
||||
|
||||
typedef struct test_fixture {
|
||||
const char *test_case_name;
|
||||
int expected;
|
||||
OSSL_CMP_CTX *cmp_ctx;
|
||||
OSSL_CMP_MSG *msg;
|
||||
X509 *cert;
|
||||
ossl_cmp_allow_unprotected_cb_t allow_unprotected_cb;
|
||||
int additional_arg;
|
||||
} CMP_VFY_TEST_FIXTURE;
|
||||
|
||||
static void tear_down(CMP_VFY_TEST_FIXTURE *fixture)
|
||||
{
|
||||
OSSL_CMP_MSG_free(fixture->msg);
|
||||
OSSL_CMP_CTX_free(fixture->cmp_ctx);
|
||||
OPENSSL_free(fixture);
|
||||
}
|
||||
|
||||
static int print_to_bio_out(const char *func, const char *file, int line,
|
||||
OSSL_CMP_severity level, const char *msg)
|
||||
{
|
||||
return OSSL_CMP_print_to_bio(bio_out, func, file, line, level, msg);
|
||||
}
|
||||
|
||||
static time_t test_time_valid = 0, test_time_after_expiration = 0;
|
||||
|
||||
static CMP_VFY_TEST_FIXTURE *set_up(const char *const test_case_name)
|
||||
{
|
||||
X509_STORE *ts = X509_STORE_new();
|
||||
CMP_VFY_TEST_FIXTURE *fixture;
|
||||
|
||||
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
|
||||
return NULL;
|
||||
fixture->test_case_name = test_case_name;
|
||||
if (ts == NULL
|
||||
|| !TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new())
|
||||
|| !OSSL_CMP_CTX_set0_trustedStore(fixture->cmp_ctx, ts)
|
||||
|| !OSSL_CMP_CTX_set_log_cb(fixture->cmp_ctx, print_to_bio_out)) {
|
||||
tear_down(fixture);
|
||||
X509_STORE_free(ts);
|
||||
return NULL;
|
||||
}
|
||||
X509_VERIFY_PARAM_set_time(X509_STORE_get0_param(ts), test_time_valid);
|
||||
X509_STORE_set_verify_cb(ts, OSSL_CMP_print_cert_verify_cb);
|
||||
return fixture;
|
||||
}
|
||||
|
||||
static X509 *srvcert = NULL;
|
||||
static X509 *clcert = NULL;
|
||||
/* chain */
|
||||
static X509 *endentity1 = NULL, *endentity2 = NULL,
|
||||
*intermediate = NULL, *root = NULL;
|
||||
/* INSTA chain */
|
||||
static X509 *insta_cert = NULL, *instaca_cert = NULL;
|
||||
|
||||
static unsigned char rand_data[OSSL_CMP_TRANSACTIONID_LENGTH];
|
||||
static OSSL_CMP_MSG *ir_unprotected, *ir_rmprotection;
|
||||
|
||||
static int flip_bit(ASN1_BIT_STRING *bitstr)
|
||||
{
|
||||
int bit_num = 7;
|
||||
int bit = ASN1_BIT_STRING_get_bit(bitstr, bit_num);
|
||||
|
||||
return ASN1_BIT_STRING_set_bit(bitstr, bit_num, !bit);
|
||||
}
|
||||
|
||||
static int execute_verify_popo_test(CMP_VFY_TEST_FIXTURE *fixture)
|
||||
{
|
||||
if ((fixture->msg = load_pkimsg(ir_protected_f)) == NULL)
|
||||
return 0;
|
||||
if (fixture->expected == 0) {
|
||||
const OSSL_CRMF_MSGS *reqs = fixture->msg->body->value.ir;
|
||||
const OSSL_CRMF_MSG *req = sk_OSSL_CRMF_MSG_value(reqs, 0);
|
||||
if (req == NULL || !flip_bit(req->popo->value.signature->signature))
|
||||
return 0;
|
||||
}
|
||||
return TEST_int_eq(fixture->expected,
|
||||
ossl_cmp_verify_popo(fixture->msg,
|
||||
fixture->additional_arg));
|
||||
}
|
||||
|
||||
static int test_verify_popo(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 1;
|
||||
EXECUTE_TEST(execute_verify_popo_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_verify_popo_bad(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 0;
|
||||
EXECUTE_TEST(execute_verify_popo_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int execute_validate_msg_test(CMP_VFY_TEST_FIXTURE *fixture)
|
||||
{
|
||||
return TEST_int_eq(fixture->expected,
|
||||
OSSL_CMP_validate_msg(fixture->cmp_ctx, fixture->msg));
|
||||
}
|
||||
|
||||
static int execute_validate_cert_path_test(CMP_VFY_TEST_FIXTURE *fixture)
|
||||
{
|
||||
X509_STORE *ts = OSSL_CMP_CTX_get0_trustedStore(fixture->cmp_ctx);
|
||||
int res = TEST_int_eq(fixture->expected,
|
||||
OSSL_CMP_validate_cert_path(fixture->cmp_ctx,
|
||||
ts, fixture->cert));
|
||||
|
||||
OSSL_CMP_CTX_print_errors(fixture->cmp_ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int test_validate_msg_mac_alg_protection(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
/* secret value belonging to cmp-test/CMP_IP_waitingStatus_PBM.der */
|
||||
const unsigned char sec_1[] = {
|
||||
'9', 'p', 'p', '8', '-', 'b', '3', '5', 'i', '-', 'X', 'd', '3',
|
||||
'Q', '-', 'u', 'd', 'N', 'R'
|
||||
};
|
||||
|
||||
fixture->expected = 1;
|
||||
if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, sec_1,
|
||||
sizeof(sec_1)))
|
||||
|| !TEST_ptr(fixture->msg = load_pkimsg(ip_waiting_f))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_mac_alg_protection_bad(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
const unsigned char sec_bad[] = {
|
||||
'9', 'p', 'p', '8', '-', 'b', '3', '5', 'i', '-', 'X', 'd', '3',
|
||||
'Q', '-', 'u', 'd', 'N', 'r'
|
||||
};
|
||||
fixture->expected = 0;
|
||||
|
||||
if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, sec_bad,
|
||||
sizeof(sec_bad)))
|
||||
|| !TEST_ptr(fixture->msg = load_pkimsg(ip_waiting_f))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int add_trusted(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
{
|
||||
return X509_STORE_add_cert(OSSL_CMP_CTX_get0_trustedStore(ctx), cert);
|
||||
}
|
||||
|
||||
static int add_untrusted(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
{
|
||||
return ossl_cmp_sk_X509_add1_cert(OSSL_CMP_CTX_get0_untrusted_certs(ctx),
|
||||
cert, 0, 0);
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_partial_chain(int expired)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
X509_STORE *ts = OSSL_CMP_CTX_get0_trustedStore(fixture->cmp_ctx);
|
||||
|
||||
fixture->expected = !expired;
|
||||
if (ts == NULL
|
||||
|| !TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))
|
||||
|| !add_trusted(fixture->cmp_ctx, srvcert)) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
} else {
|
||||
X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts);
|
||||
X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN);
|
||||
if (expired)
|
||||
X509_VERIFY_PARAM_set_time(vpm, test_time_after_expiration);
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_trusted_ok(void)
|
||||
{
|
||||
return test_validate_msg_signature_partial_chain(0);
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_trusted_expired(void)
|
||||
{
|
||||
return test_validate_msg_signature_partial_chain(1);
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_srvcert_wrong(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 0;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))
|
||||
|| !TEST_true(OSSL_CMP_CTX_set1_srvCert(fixture->cmp_ctx, clcert))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_srvcert(int bad_sig)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = !bad_sig;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))
|
||||
|| !TEST_true(OSSL_CMP_CTX_set1_srvCert(fixture->cmp_ctx, srvcert))
|
||||
|| (bad_sig && !flip_bit(fixture->msg->protection))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_bad(void)
|
||||
{
|
||||
return test_validate_msg_signature_srvcert(1);
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_sender_cert_srvcert(void)
|
||||
{
|
||||
return test_validate_msg_signature_srvcert(0);
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_sender_cert_untrusted(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 1;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_0_extracerts))
|
||||
|| !add_trusted(fixture->cmp_ctx, instaca_cert)
|
||||
|| !add_untrusted(fixture->cmp_ctx, insta_cert)) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_sender_cert_trusted(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 1;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_0_extracerts))
|
||||
|| !add_trusted(fixture->cmp_ctx, instaca_cert)
|
||||
|| !add_trusted(fixture->cmp_ctx, insta_cert)) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_sender_cert_extracert(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 1;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_2_extracerts))
|
||||
|| !add_trusted(fixture->cmp_ctx, instaca_cert)) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int test_validate_msg_signature_sender_cert_absent(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 0;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_0_extracerts))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int test_validate_with_sender(X509_NAME *name, int expected)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = expected;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))
|
||||
|| !TEST_true(OSSL_CMP_CTX_set1_expected_sender(fixture->cmp_ctx, name))
|
||||
|| !TEST_true(OSSL_CMP_CTX_set1_srvCert(fixture->cmp_ctx, srvcert))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_expected_sender(void)
|
||||
{
|
||||
return test_validate_with_sender(X509_get_subject_name(srvcert), 1);
|
||||
}
|
||||
|
||||
static int test_validate_msg_signature_unexpected_sender(void)
|
||||
{
|
||||
return test_validate_with_sender(X509_get_subject_name(root), 0);
|
||||
}
|
||||
|
||||
static int test_validate_msg_unprotected_request(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
fixture->expected = 0;
|
||||
if (!TEST_ptr(fixture->msg = load_pkimsg(ir_unprotected_f))) {
|
||||
tear_down(fixture);
|
||||
fixture = NULL;
|
||||
}
|
||||
EXECUTE_TEST(execute_validate_msg_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void setup_path(CMP_VFY_TEST_FIXTURE **fixture, X509 *wrong, int expired)
|
||||
{
|
||||
(*fixture)->cert = endentity2;
|
||||
(*fixture)->expected = wrong == NULL && !expired;
|
||||
if (expired) {
|
||||
X509_STORE *ts = OSSL_CMP_CTX_get0_trustedStore((*fixture)->cmp_ctx);
|
||||
X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts);
|
||||
X509_VERIFY_PARAM_set_time(vpm, test_time_after_expiration);
|
||||
}
|
||||
if (!add_trusted((*fixture)->cmp_ctx, wrong == NULL ? root : wrong)
|
||||
|| !add_untrusted((*fixture)->cmp_ctx, endentity1)
|
||||
|| !add_untrusted((*fixture)->cmp_ctx, intermediate)) {
|
||||
tear_down((*fixture));
|
||||
(*fixture) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int test_validate_cert_path_ok(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_path(&fixture, NULL, 0);
|
||||
EXECUTE_TEST(execute_validate_cert_path_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_cert_path_wrong_anchor(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_path(&fixture, srvcert /* wrong/non-root cert */, 0);
|
||||
EXECUTE_TEST(execute_validate_cert_path_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_validate_cert_path_expired(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_path(&fixture, NULL, 1);
|
||||
EXECUTE_TEST(execute_validate_cert_path_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int execute_MSG_check_received_test(CMP_VFY_TEST_FIXTURE *fixture)
|
||||
{
|
||||
const OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(fixture->msg);
|
||||
const ASN1_OCTET_STRING *tid = OSSL_CMP_HDR_get0_transactionID(hdr);
|
||||
|
||||
if (!TEST_int_eq(fixture->expected,
|
||||
ossl_cmp_msg_check_received(fixture->cmp_ctx,
|
||||
fixture->msg,
|
||||
fixture->allow_unprotected_cb,
|
||||
fixture->additional_arg)))
|
||||
return 0;
|
||||
|
||||
if (fixture->expected < 0) /* error expected aready during above check */
|
||||
return 1;
|
||||
return
|
||||
TEST_int_eq(0,
|
||||
ASN1_OCTET_STRING_cmp(ossl_cmp_hdr_get0_senderNonce(hdr),
|
||||
fixture->cmp_ctx->recipNonce))
|
||||
&& TEST_int_eq(0,
|
||||
ASN1_OCTET_STRING_cmp(tid,
|
||||
fixture->cmp_ctx->transactionID));
|
||||
}
|
||||
|
||||
static int allow_unprotected(const OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
int invalid_protection, int allow)
|
||||
{
|
||||
return allow;
|
||||
}
|
||||
|
||||
static void setup_check_received(CMP_VFY_TEST_FIXTURE **fixture, int expected,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int arg,
|
||||
const unsigned char *trid_data,
|
||||
const unsigned char *nonce_data)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx = (*fixture)->cmp_ctx;
|
||||
int nonce_len = OSSL_CMP_SENDERNONCE_LENGTH;
|
||||
|
||||
(*fixture)->expected = expected;
|
||||
(*fixture)->allow_unprotected_cb = cb;
|
||||
(*fixture)->additional_arg = arg;
|
||||
(*fixture)->msg = OSSL_CMP_MSG_dup(ir_rmprotection);
|
||||
if ((*fixture)->msg == NULL
|
||||
|| (nonce_data != NULL
|
||||
&& !ossl_cmp_asn1_octet_string_set1_bytes(&ctx->senderNonce,
|
||||
nonce_data, nonce_len))) {
|
||||
tear_down((*fixture));
|
||||
(*fixture) = NULL;
|
||||
}
|
||||
else if (trid_data != NULL) {
|
||||
ASN1_OCTET_STRING *trid = ASN1_OCTET_STRING_new();
|
||||
if (trid == NULL
|
||||
|| !ASN1_OCTET_STRING_set(trid, trid_data,
|
||||
OSSL_CMP_TRANSACTIONID_LENGTH)
|
||||
|| !OSSL_CMP_CTX_set1_transactionID(ctx, trid)) {
|
||||
tear_down((*fixture));
|
||||
(*fixture) = NULL;
|
||||
}
|
||||
ASN1_OCTET_STRING_free(trid);
|
||||
}
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_no_protection_no_cb(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, -1, NULL, 0, NULL, NULL);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_no_protection_restrictive_cb(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, -1, allow_unprotected, 0, NULL, NULL);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_no_protection_permissive_cb(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, OSSL_CMP_PKIBODY_IP, allow_unprotected, 1,
|
||||
NULL, NULL);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_check_transaction_id(void)
|
||||
{
|
||||
/* Transaction id belonging to CMP_IR_rmprotection.der */
|
||||
const unsigned char trans_id[OSSL_CMP_TRANSACTIONID_LENGTH] = {
|
||||
0x39, 0xB6, 0x90, 0x28, 0xC4, 0xBC, 0x7A, 0xF6,
|
||||
0xBE, 0xC6, 0x4A, 0x88, 0x97, 0xA6, 0x95, 0x0B
|
||||
};
|
||||
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, OSSL_CMP_PKIBODY_IP, allow_unprotected, 1,
|
||||
trans_id, NULL);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_check_transaction_id_bad(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, -1, allow_unprotected, 1, rand_data, NULL);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_check_recipient_nonce(void)
|
||||
{
|
||||
/* Recipient nonce belonging to CMP_IP_ir_rmprotection.der */
|
||||
const unsigned char rec_nonce[OSSL_CMP_SENDERNONCE_LENGTH] = {
|
||||
0x48, 0xF1, 0x71, 0x1F, 0xE5, 0xAF, 0x1C, 0x8B,
|
||||
0x21, 0x97, 0x5C, 0x84, 0x74, 0x49, 0xBA, 0x32
|
||||
};
|
||||
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, OSSL_CMP_PKIBODY_IP, allow_unprotected, 1,
|
||||
NULL, rec_nonce);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int test_MSG_check_received_check_recipient_nonce_bad(void)
|
||||
{
|
||||
SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
|
||||
setup_check_received(&fixture, -1, allow_unprotected, 1, NULL, rand_data);
|
||||
EXECUTE_TEST(execute_MSG_check_received_test, tear_down);
|
||||
return result;
|
||||
}
|
||||
|
||||
void cleanup_tests(void)
|
||||
{
|
||||
X509_free(srvcert);
|
||||
X509_free(clcert);
|
||||
X509_free(endentity1);
|
||||
X509_free(endentity2);
|
||||
X509_free(intermediate);
|
||||
X509_free(root);
|
||||
X509_free(insta_cert);
|
||||
X509_free(instaca_cert);
|
||||
OSSL_CMP_MSG_free(ir_unprotected);
|
||||
OSSL_CMP_MSG_free(ir_rmprotection);
|
||||
return;
|
||||
}
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
/* Set test time stamps */
|
||||
struct tm ts = { 0 };
|
||||
|
||||
ts.tm_year = 2018 - 1900; /* 2018 */
|
||||
ts.tm_mon = 1; /* February */
|
||||
ts.tm_mday = 18; /* 18th */
|
||||
test_time_valid = mktime(&ts); /* February 18th 2018 */
|
||||
ts.tm_year += 10; /* February 18th 2028 */
|
||||
test_time_after_expiration = mktime(&ts);
|
||||
|
||||
RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH);
|
||||
if (!TEST_ptr(server_f = test_get_argument(0))
|
||||
|| !TEST_ptr(client_f = test_get_argument(1))
|
||||
|| !TEST_ptr(endentity1_f = test_get_argument(2))
|
||||
|| !TEST_ptr(endentity2_f = test_get_argument(3))
|
||||
|| !TEST_ptr(root_f = test_get_argument(4))
|
||||
|| !TEST_ptr(intermediate_f = test_get_argument(5))
|
||||
|| !TEST_ptr(ir_protected_f = test_get_argument(6))
|
||||
|| !TEST_ptr(ir_unprotected_f = test_get_argument(7))
|
||||
|| !TEST_ptr(ip_waiting_f = test_get_argument(8))
|
||||
|| !TEST_ptr(ir_rmprotection_f = test_get_argument(9))
|
||||
|| !TEST_ptr(instacert_f = test_get_argument(10))
|
||||
|| !TEST_ptr(instaca_f = test_get_argument(11))
|
||||
|| !TEST_ptr(ir_protected_0_extracerts = test_get_argument(12))
|
||||
|| !TEST_ptr(ir_protected_2_extracerts = test_get_argument(13))) {
|
||||
TEST_error("usage: cmp_vfy_test server.crt client.crt "
|
||||
"EndEntity1.crt EndEntity2.crt "
|
||||
"Root_CA.crt Intermediate_CA.crt "
|
||||
"CMP_IR_protected.der CMP_IR_unprotected.der "
|
||||
"IP_waitingStatus_PBM.der IR_rmprotection.der "
|
||||
"insta.cert.pem insta_ca.cert.pem "
|
||||
"IR_protected_0_extraCerts.der "
|
||||
"IR_protected_2_extraCerts.der\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load certificates for cert chain */
|
||||
if (!TEST_ptr(endentity1 = load_pem_cert(endentity1_f))
|
||||
|| !TEST_ptr(endentity2 = load_pem_cert(endentity2_f))
|
||||
|| !TEST_ptr(root = load_pem_cert(root_f))
|
||||
|| !TEST_ptr(intermediate = load_pem_cert(intermediate_f)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_ptr(insta_cert = load_pem_cert(instacert_f))
|
||||
|| !TEST_ptr(instaca_cert = load_pem_cert(instaca_f)))
|
||||
goto err;
|
||||
|
||||
/* Load certificates for message validation */
|
||||
if (!TEST_ptr(srvcert = load_pem_cert(server_f))
|
||||
|| !TEST_ptr(clcert = load_pem_cert(client_f)))
|
||||
goto err;
|
||||
if (!TEST_int_eq(1, RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH)))
|
||||
goto err;
|
||||
if (!TEST_ptr(ir_unprotected = load_pkimsg(ir_unprotected_f))
|
||||
|| !TEST_ptr(ir_rmprotection = load_pkimsg(ir_rmprotection_f)))
|
||||
goto err;
|
||||
|
||||
/* Message validation tests */
|
||||
ADD_TEST(test_verify_popo);
|
||||
ADD_TEST(test_verify_popo_bad);
|
||||
ADD_TEST(test_validate_msg_signature_trusted_ok);
|
||||
ADD_TEST(test_validate_msg_signature_trusted_expired);
|
||||
ADD_TEST(test_validate_msg_signature_srvcert_wrong);
|
||||
ADD_TEST(test_validate_msg_signature_bad);
|
||||
ADD_TEST(test_validate_msg_signature_sender_cert_srvcert);
|
||||
ADD_TEST(test_validate_msg_signature_sender_cert_untrusted);
|
||||
ADD_TEST(test_validate_msg_signature_sender_cert_trusted);
|
||||
ADD_TEST(test_validate_msg_signature_sender_cert_extracert);
|
||||
ADD_TEST(test_validate_msg_signature_sender_cert_absent);
|
||||
ADD_TEST(test_validate_msg_signature_expected_sender);
|
||||
ADD_TEST(test_validate_msg_signature_unexpected_sender);
|
||||
ADD_TEST(test_validate_msg_unprotected_request);
|
||||
ADD_TEST(test_validate_msg_mac_alg_protection);
|
||||
ADD_TEST(test_validate_msg_mac_alg_protection_bad);
|
||||
|
||||
/* Cert path validation tests */
|
||||
ADD_TEST(test_validate_cert_path_ok);
|
||||
ADD_TEST(test_validate_cert_path_expired);
|
||||
ADD_TEST(test_validate_cert_path_wrong_anchor);
|
||||
|
||||
ADD_TEST(test_MSG_check_received_no_protection_no_cb);
|
||||
ADD_TEST(test_MSG_check_received_no_protection_restrictive_cb);
|
||||
ADD_TEST(test_MSG_check_received_no_protection_permissive_cb);
|
||||
ADD_TEST(test_MSG_check_received_check_transaction_id);
|
||||
ADD_TEST(test_MSG_check_received_check_transaction_id_bad);
|
||||
ADD_TEST(test_MSG_check_received_check_recipient_nonce);
|
||||
ADD_TEST(test_MSG_check_received_check_recipient_nonce_bad);
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
cleanup_tests();
|
||||
return 0;
|
||||
|
||||
}
|
36
test/recipes/65-test_cmp_vfy.t
Normal file
36
test/recipes/65-test_cmp_vfy.t
Normal file
@ -0,0 +1,36 @@
|
||||
#! /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_vfy");
|
||||
|
||||
plan skip_all => "This test is not supported in a no-cmp build"
|
||||
if disabled("cmp");
|
||||
|
||||
plan skip_all => "This test is not supported in a no-ec build"
|
||||
if disabled("ec");
|
||||
|
||||
plan tests => 1;
|
||||
|
||||
ok(run(test(["cmp_vfy_test",
|
||||
data_file("server.crt"), data_file("client.crt"),
|
||||
data_file("EndEntity1.crt"), data_file("EndEntity2.crt"),
|
||||
data_file("Root_CA.crt"), data_file("Intermediate_CA.crt"),
|
||||
data_file("IR_protected.der"),
|
||||
data_file("IR_unprotected.der"),
|
||||
data_file("IP_waitingStatus_PBM.der"),
|
||||
data_file("IR_rmprotection.der"),
|
||||
data_file("insta.cert.pem"),
|
||||
data_file("insta_ca.cert.pem"),
|
||||
data_file("IR_protected_0_extraCerts.der"),
|
||||
data_file("IR_protected_2_extraCerts.der")])));
|
16
test/recipes/65-test_cmp_vfy_data/EndEntity1.crt
Normal file
16
test/recipes/65-test_cmp_vfy_data/EndEntity1.crt
Normal file
@ -0,0 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICnDCCAYSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdSb290
|
||||
IENBMB4XDTE3MTEwODE1NDgwMFoXDTE4MTEwODExMTkwMFowETEPMA0GA1UEAxMG
|
||||
Q2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtNiWJufEotHe
|
||||
p6E/4b0laX7K1NRamNoUokLIsq78RoBieBXaGxIdbT6zmhLnLmZdb0UN3v7FUP75
|
||||
rqPN2yyj3TbS4o5ilh5El8bDDAPhW5lthCddvH/uBziRAM5oIB4xxOumNbgHpLUT
|
||||
Clh49sdXd4ydYpCTWld5emRouBmMUeP/0EkyWMBIrHGSBxrqtFVRXhxvVHImQv6Z
|
||||
hIKql7dCVCZbhUtxw6sLxIGL4xlhKoM2o31k4I/9tjZrWSZZ7KAIOlOLrjxZc/bQ
|
||||
MwvxVUgS+C+iXzhCY8v+N/K37jwtAAk4C1aOGv/VygNcN0C/ynfKSzFmtnfei4+3
|
||||
6GC7HtFzewIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQB3GYpPSCCYsJM5owKcODr/
|
||||
I1aJ8jQ+u5jCKjvYLp6Cnbr4AbRXzvKuMyV6UfIAQbrGOxAClvX++5/ZQbhY+TxN
|
||||
iiUM3yr5yYCLqj4MeYHhJ3gOzcppAO9LQ9V7eA8C830giZMm3cpApFSLP8CpwNUD
|
||||
W/fgoQfaOae5IYPZdea88Gmt5RVNbtHgVqtm4ifTQo577kfxTeh20s+M6pgYW3/R
|
||||
vftXy2ITEtk/j3NcRvOyZ7Bu1mAg7wNeUjL+gDWAaxs16LsWsCsUGwfr/Z2Rq1CF
|
||||
zB0XwIyigkVLDLqDzUShcw0Eb/zYy2KXsxNWA2tb27mw+T+tmmOszpn7JjLrlVks
|
||||
-----END CERTIFICATE-----
|
13
test/recipes/65-test_cmp_vfy_data/EndEntity2.crt
Normal file
13
test/recipes/65-test_cmp_vfy_data/EndEntity2.crt
Normal file
@ -0,0 +1,13 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB3zCCAZSgAwIBAgIBBjAKBggqhkjOPQQDAzAVMRMwEQYDVQQDEwpad2lzY2hl
|
||||
bkNBMB4XDTE3MTEwODE2MDUwMFoXDTE4MTEwODExMTkwMFowEjEQMA4GA1UEAxMH
|
||||
Q2xpZW50MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTYlibnxKLR
|
||||
3qehP+G9JWl+ytTUWpjaFKJCyLKu/EaAYngV2hsSHW0+s5oS5y5mXW9FDd7+xVD+
|
||||
+a6jzdsso9020uKOYpYeRJfGwwwD4VuZbYQnXbx/7gc4kQDOaCAeMcTrpjW4B6S1
|
||||
EwpYePbHV3eMnWKQk1pXeXpkaLgZjFHj/9BJMljASKxxkgca6rRVUV4cb1RyJkL+
|
||||
mYSCqpe3QlQmW4VLccOrC8SBi+MZYSqDNqN9ZOCP/bY2a1kmWeygCDpTi648WXP2
|
||||
0DML8VVIEvgvol84QmPL/jfyt+48LQAJOAtWjhr/1coDXDdAv8p3yksxZrZ33ouP
|
||||
t+hgux7Rc3sCAwEAAaMNMAswCQYDVR0TBAIwADAKBggqhkjOPQQDAwM5ADA2AhkA
|
||||
qASBLwTauET6FGp/EBe7b/99jTyGB861AhkA5ILGkLX4KmjRkTcNxJ3JKB1Sumya
|
||||
cbqF
|
||||
-----END CERTIFICATE-----
|
BIN
test/recipes/65-test_cmp_vfy_data/IP_waitingStatus_PBM.der
Normal file
BIN
test/recipes/65-test_cmp_vfy_data/IP_waitingStatus_PBM.der
Normal file
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
Reference#: 4787
|
||||
Secret Value: 9pp8-b35i-Xd3Q-udNR
|
BIN
test/recipes/65-test_cmp_vfy_data/IR_protected.der
Normal file
BIN
test/recipes/65-test_cmp_vfy_data/IR_protected.der
Normal file
Binary file not shown.
BIN
test/recipes/65-test_cmp_vfy_data/IR_protected_0_extraCerts.der
Executable file
BIN
test/recipes/65-test_cmp_vfy_data/IR_protected_0_extraCerts.der
Executable file
Binary file not shown.
BIN
test/recipes/65-test_cmp_vfy_data/IR_protected_2_extraCerts.der
Executable file
BIN
test/recipes/65-test_cmp_vfy_data/IR_protected_2_extraCerts.der
Executable file
Binary file not shown.
BIN
test/recipes/65-test_cmp_vfy_data/IR_rmprotection.der
Normal file
BIN
test/recipes/65-test_cmp_vfy_data/IR_rmprotection.der
Normal file
Binary file not shown.
BIN
test/recipes/65-test_cmp_vfy_data/IR_unprotected.der
Normal file
BIN
test/recipes/65-test_cmp_vfy_data/IR_unprotected.der
Normal file
Binary file not shown.
12
test/recipes/65-test_cmp_vfy_data/Intermediate_CA.crt
Normal file
12
test/recipes/65-test_cmp_vfy_data/Intermediate_CA.crt
Normal file
@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB1jCBv6ADAgECAgEFMA0GCSqGSIb3DQEBDQUAMBIxEDAOBgNVBAMTB1Jvb3Qg
|
||||
Q0EwHhcNMTcxMTA4MTYwNDAwWhcNMTgxMTA4MTExOTAwWjAVMRMwEQYDVQQDEwpa
|
||||
d2lzY2hlbkNBMEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAE9bJcmZWj2CmO6aW8
|
||||
9Qylkj1WgPREf9/s4Z1VYqFODeJnebPXFBLVH/aoGxnds9E9oxAwDjAMBgNVHRME
|
||||
BTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQBwQD4NTIWMMevEsSrBpKjjQEWc81Ct
|
||||
eXoyAXr/d8wgVyuIZe9C7ekxPQCwowcmONUyeYQv9N2eYpdhkAQuk6DS4+aDR4s7
|
||||
I6rg5R5CUGGla5NUxM0BKIS3ZIezvEGlP1NFN+HBgJI7ZIIYQ3zDr0EYgo4J7Xvm
|
||||
5p58pcCZSsbVyKwKs6T+rTzOVVmJ2L1bWzywZEDmzxMkPmA6fP9XtB4Kx/b4oviw
|
||||
TEQl3Jf9EkBvBkKX2rRJs7aMJo4MwOnE4HHOV5GAQqhGrXltsuXmVfIQPtRN4xlK
|
||||
oNf/FukI1NcBh4A/iY4PmbyxHYmKy6qjFjng2u2VFtH15HDT4XlLP5gq
|
||||
-----END CERTIFICATE-----
|
17
test/recipes/65-test_cmp_vfy_data/Root_CA.crt
Normal file
17
test/recipes/65-test_cmp_vfy_data/Root_CA.crt
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICrzCCAZegAwIBAgIBATANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdSb290
|
||||
IENBMB4XDTE3MTEwODE1NDUwMFoXDTE4MTEwODExMTkwMFowEjEQMA4GA1UEAxMH
|
||||
Um9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALiHdLAD2Wu+
|
||||
C5UDMK6WCL53Wz0CeU61RRRlGEVSqHrQOWnffgVutgftzsddxxgJJyGsqKo1B+nQ
|
||||
vapyJyugYJWYNQLN5+iffe4y1UBPnHMQFHiZ4cNR6PB0eHja2wpcN3QmJzOcpRYE
|
||||
xf+QQwJNFqhRi0cZGfd/JfFi/ybJalqClbnYMPcJo7g6S7M3lWbOnEOUWnbM2EBp
|
||||
h849mC+kd80vXcRcb7U/3MJKK3Ee72TDye5/kWFf9zcxj2ac0oCiS66JKYobiVJr
|
||||
NmbGM0I9U6T6ejXVUu2J3pGUFlcf3RCUYf1aWhkmzEzbm/FGMRJ7vVyCXm/OWIh9
|
||||
bqtwH5YfljsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
|
||||
AQEAF7tSa9oVan7kPR5/TXB330Ca1xQt5C38afaJbacR9mM8ZkL0HceQTuJGrnAR
|
||||
4kK7CaB5iraU6Lxyql7drq8aixz/7TXna6c172J6HxDeFhQMeSt1LAh7XN5Ir6Y6
|
||||
iO7XD5I5lw3Xv6qvhoD0ktkNk/WtF7aBw2ZAi+RcDMgWzWjoS4WqMbvWEHw10j9b
|
||||
s8R0YG4yi6wb89UNIMfQtC2XviHKcRS9MzIJQHw73r2EY2t6o9TO+5ukHYDB6/Zo
|
||||
/CLXu21MzsFvhupHgX6zdptU324tq2za1+4LvmOHSW+D36jEPT22SndXmHo5VmAn
|
||||
6bQ52MhBI0rrWwju9aBpVzsUUg==
|
||||
-----END CERTIFICATE-----
|
4
test/recipes/65-test_cmp_vfy_data/chain.txt
Normal file
4
test/recipes/65-test_cmp_vfy_data/chain.txt
Normal file
@ -0,0 +1,4 @@
|
||||
1 - Root_CA (self-signed)
|
||||
1.1 - EndEntity1
|
||||
1.2 Intermediate_CA
|
||||
1.2.1 EndEntity2
|
17
test/recipes/65-test_cmp_vfy_data/client.crt
Normal file
17
test/recipes/65-test_cmp_vfy_data/client.crt
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICtTCCAZ2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAeMRwwGgYDVQQKExNjbGll
|
||||
bnQgb3JnYW5pemF0aW9uMB4XDTE4MDIwNjEyNDYwMFoXDTE5MDIwNjEyNDYwMFow
|
||||
HjEcMBoGA1UEChMTY2xpZW50IG9yZ2FuaXphdGlvbjCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBALf0KDl07RlJlQVQcibB+JiUyXthFz4nzIkFVNISORCG
|
||||
JpTUMLLWxhF7Sc1li7gzvMAvx77SUThaNEOd0d2MJBbOXmZ9MtAOy8yHzRejBpw1
|
||||
mn9e0FKCI8rz3ttivspsGUIsRDhvMxuOol3lQ93QjfI593D7BOfBGdhsivD8m6+P
|
||||
EzF400iOSsbo3VPlArA+xTHiCyJ+E9p3yFGvzQrmK/MjM3lW3l3tARJmbXINIOio
|
||||
PnVmh4nsc9awqDGQdQTup/EjuY15AR4Vck7Zf9e+6U9t7Ow7aaZ5gX07FNnnqlVs
|
||||
48Lj/5a2Qgh482SQNvvRWAkPwTQNZ40ThKvOR/sB3iUCAwEAATANBgkqhkiG9w0B
|
||||
AQUFAAOCAQEAUSZBAR22ICoO7oPKMpfxwIHDAODv6jEHx2fSTpwxqodVqwF8ghAS
|
||||
PvJwQ4+7+yny4ieX9iVicRdXXT8kEOQL5/3/Q+cBj/BzYE0VGxo4YloHQwWNdSg0
|
||||
B1oQ/4dAnDntGnXHDJMSZCGq/jj4/56XSrPymzR2jgOQNqnEkMM9/SpW7MirixJA
|
||||
ZBR5Oc97vKaAH89ucsTu0neVMTXgywdBiy1W8bo4XxquK6VDRHlLj4gMLBpaG0mW
|
||||
r5ST1gs8j63nK/eZ7AuTV/tvI25reXT+2wOKAgPEcd02Fh61TO4IPD4GDidEHvAw
|
||||
6m66U9eFVezkxDvjE0X5voFnsBl4qTSZ/A==
|
||||
-----END CERTIFICATE-----
|
25
test/recipes/65-test_cmp_vfy_data/insta.cert.pem
Executable file
25
test/recipes/65-test_cmp_vfy_data/insta.cert.pem
Executable file
@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEHTCCAwWgAwIBAgIEBtqJKDANBgkqhkiG9w0BAQsFADA6MQswCQYDVQQGEwJG
|
||||
STETMBEGA1UECgwKSW5zdGEgRGVtbzEWMBQGA1UEAwwNSW5zdGEgRGVtbyBDQTAe
|
||||
Fw0xODAxMzAxMDE0MjNaFw0xODA0MzAyMzU5NTlaMBAxDjAMBgNVBAMMBXRlc3Qx
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoiNNxo5pwk1lD1em3mad
|
||||
bpKz86GSYyGlQtd0ZhIX1tOUFo9lFex7n5Osv0A99pKb+7EKqB9Ghg6mJ29kIUUm
|
||||
LACnfZJ/q+U6s9T4zFrYyXweUNJvQgbA2ojDPyVoRp2T1ekahPh4DpxPWNKfYECD
|
||||
RbrxkHMM3WiIqYFLU8hYvEMGSWRHHbnS/vG7MTaVDkR8d0zixTOp0fST5c1UUTqp
|
||||
pYlThac/BG1kk3hyjIjz5o7lspfX3s/eAYgT9GhYHL6Uy4o4OqCleR39aVc0dMrr
|
||||
jb7hsmX6ecNwqJOE5AHHOG4Ti6CbweSOcdH5PRFzdpao5rlTErsFHlUSTca4mfVe
|
||||
WwIDAQABo4IBUzCCAU8wHwYDVR0jBBgwFoAUPHjduMGNV/UFKl5t4FhySvpEJWEw
|
||||
HQYDVR0OBBYEFD0oLwov3vSGa1f9bIKGzWoPP0A1MCcGA1UdEQQgMB6CBGFiLmOC
|
||||
BGRlLmaCBHRlc3SHBAECA/+HBAQFBgcweAYDVR0fBHEwbzBtoGugaYZnbGRhcDov
|
||||
L3BraS5jZXJ0aWZpY2F0ZS5maTozODkvQ049SW5zdGElMjBEZW1vJTIwQ0EsTz1J
|
||||
bnN0YSUyMERlbW8sQz1GST9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFy
|
||||
eTBqBggrBgEFBQcBAQReMFwwWgYIKwYBBQUHMAKGTmxkYXA6Ly93d3cuY2VydGlm
|
||||
aWNhdGUuZmk6Mzg5L0NOPUluc3RhIERlbW8gQ0EsTz1JbnN0YSBEZW1vLEM9Rkk/
|
||||
Y2FDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEAbIRfAbU0v2RWZg6lkjZg
|
||||
58fi4lT7Xk64sK4G/QLZ8TR/jg5UR0J5IvYt52YBjs/tjwJokkaW7+DyhVKkPrGs
|
||||
oexpdLRSnXBv33+Yj+MZbSfrIX1Ox7up+ovs8le4viSlUqIDWBuuUBfZ16BFMmnB
|
||||
UwDar8p/ci9ReKJH+FmvxlHbTHdMznZooSxTZm96HTutuiULL/SzZ2FpUsd7G5EE
|
||||
mRA6uRVV1tuysD15H+9paqVwd0RaKee8Z63cDi3NXOxUcCnpINHrjVsdcW47/73V
|
||||
IgfU4t39BKNiQNL0ADYpCyrpntTpsyZWrNmYzXMgLYEXxi4s6obusY0I3Qg+U31o
|
||||
Uw==
|
||||
-----END CERTIFICATE-----
|
27
test/recipes/65-test_cmp_vfy_data/insta.priv.pem
Executable file
27
test/recipes/65-test_cmp_vfy_data/insta.priv.pem
Executable file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAoiNNxo5pwk1lD1em3madbpKz86GSYyGlQtd0ZhIX1tOUFo9l
|
||||
Fex7n5Osv0A99pKb+7EKqB9Ghg6mJ29kIUUmLACnfZJ/q+U6s9T4zFrYyXweUNJv
|
||||
QgbA2ojDPyVoRp2T1ekahPh4DpxPWNKfYECDRbrxkHMM3WiIqYFLU8hYvEMGSWRH
|
||||
HbnS/vG7MTaVDkR8d0zixTOp0fST5c1UUTqppYlThac/BG1kk3hyjIjz5o7lspfX
|
||||
3s/eAYgT9GhYHL6Uy4o4OqCleR39aVc0dMrrjb7hsmX6ecNwqJOE5AHHOG4Ti6Cb
|
||||
weSOcdH5PRFzdpao5rlTErsFHlUSTca4mfVeWwIDAQABAoIBAQCUYAZevBjgbP8c
|
||||
qTPVtsY/WBVB0Qwrl7CqmIy2k7wpJfoRIyx4ga8n+3ZMlredm9EO5ZdA/04EhAdd
|
||||
czyIjcU+42JjMduQLPgpda4xJLnauLDteYXDQHbgBePXN55TcQTG7skMAm2rwTOD
|
||||
r0uWQ7Nd7pP9gqu1OmJF7EJI68D4llCU1FrOrliwSDzHWP3p4QmCW3M9PQJ68xw1
|
||||
gE7X1QflROGivcFoRgcgeoJDzpxveGvPbEn6Q+05/FMRVxjqWhpxdZ9/SL7iRz1e
|
||||
45T+P9a8OLgTyErT3Lp/f/vuHA1tlbAYumhSnxXsb+nHi80aDcImOrNQHAp076Ik
|
||||
bkZ1NpOxAoGBAM3Ulgi2hUPdoAMFtHZF8eBHRzn+4uTfY2s33wObiUJQ8VbGDeJY
|
||||
ifCfOwLThiAXAqktrs7ItwWDYmzd5xPYGQeWoKcBEoZ+dvaaOe8H7TCMnjB3R3i1
|
||||
ACSDHo/3c+NfFOnPJtXL85jeAqGYH50uOtYmYaBVe6xASTBgNvP7snYHAoGBAMmo
|
||||
ZBQqgIhoqMRapGh6n4OpzH0Nt9ruOTJoteAfbLdAu7X+wAaMuxEaAmZQRDYj0lzX
|
||||
Ty8DlKSy7vfvXtghxMBEv4+dsYpagXcUOeEZSPfu1c3e253dAov6C0MdREKWBT7P
|
||||
+NwPBowPy0CP/yBeHaw7d/P7/SYIoPXLGraGl6ANAoGBAMmmce7LUjgw0mjjl+8f
|
||||
i14cts08x3FO4YnTTOut34VW43oNwuBzuYBBn4CfVpHtuS+hj9cKkTQXib/6jj7E
|
||||
wZDLo0y6Ijodf9MNOaDSdS/RM9Frqlu5iBA9XR3SYnjpWAXQas2eaGLlblJ+RMqq
|
||||
1f2j0JVR6j3RJWL9gBj8B9TVAoGBALYZrs4bF1iXEhfGNoL2gIdX1QX0VluIFfR0
|
||||
ZBDQr87H0Ppm4qbHfMHTt+kGgKJXNMaL08CDvj4AKxWPfhk0XUS2kDmzUDi8w/5x
|
||||
MFcaCy+A6Gdw4OcsRfl7QaJIknSCnpf7HCI0G1hthsB1iBCFjMwUI50ap54p2pg6
|
||||
4ZOD9PYdAoGAERi5Hlq7+rJeDi3VunKHySqV9mvbOPNclEUmAdKi1yuu3INF1Zgv
|
||||
Lf432ZI/Ufk2g888ed5ZGE1IMULc2tgSIAMzdX4ZYI4uGFLkHWzSOM6a7NCeZuVt
|
||||
W+NgUYa2qsqFEd9kqaoDbNry+nPvLM7fWXvBoE4oNkeJhHjOIabBPvw=
|
||||
-----END RSA PRIVATE KEY-----
|
22
test/recipes/65-test_cmp_vfy_data/insta_ca.cert.pem
Executable file
22
test/recipes/65-test_cmp_vfy_data/insta_ca.cert.pem
Executable file
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDkDCCAnigAwIBAgIDCZU1MA0GCSqGSIb3DQEBBQUAMDoxCzAJBgNVBAYTAkZJ
|
||||
MRMwEQYDVQQKEwpJbnN0YSBEZW1vMRYwFAYDVQQDEw1JbnN0YSBEZW1vIENBMB4X
|
||||
DTA2MDEwMjA4NDgzOFoXDTI1MTIzMTA4NDgzOFowOjELMAkGA1UEBhMCRkkxEzAR
|
||||
BgNVBAoTCkluc3RhIERlbW8xFjAUBgNVBAMTDUluc3RhIERlbW8gQ0EwggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF57bSwj+hZnkgLyLtFsoNIN19qBv9
|
||||
GIoqFaCiPvw6VQgMXR15t+Z5sdYHdydGp875yJD4wDq2K7cjMoCXALxLeyp6dCY6
|
||||
WPC6Hk3QvZtMRuDAz8+0Nb5qaC4+O+7c7j1h/Gs8Jpj+TUuSkmtlCVIGPSWkWaQl
|
||||
FhLWeUnKRW8bj1CJQguV7igF19kGQKUZ/VZj+n5xIXKHc8njC1ZrS/s0IBFViQkZ
|
||||
63nTdNPLHQ4Xu8uKrbJbYEK1S4KVNH3L9yA4ut+brqX8n6OulTsKntvMdwNWZdor
|
||||
KoM15D3lmM7QUGDflJdSQ/qvBVTda+ccrT21sp4hdwwiU01vxQguT26JAgMBAAGj
|
||||
gZ4wgZswHwYDVR0jBBgwFoAUPHjduMGNV/UFKl5t4FhySvpEJWEwHQYDVR0OBBYE
|
||||
FDx43bjBjVf1BSpebeBYckr6RCVhMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8E
|
||||
CDAGAQH/AgEAMDUGCWCGSAGG+EIBDQQoFiZJbnN0YSBEZW1vIENBIC0gb25seSBm
|
||||
b3IgZGVtbyBwdXJwb3NlczANBgkqhkiG9w0BAQUFAAOCAQEAuVRmRimTxVTZMNXi
|
||||
3u4bRCq7GxJ4Lonx3mocxYiwBjCYwqn5dPAd4AHrA1HWYCEvIPo52FibpUNNljqH
|
||||
v7CSoEBg2f4If6cFtwudobqNvf8Z50CAnxlwpPy4k+EbXlh49/uZBtu8+Lc2Ss7L
|
||||
QaNHHiOeHxYeGX7pTcr6fnXQWAbbn4SLyqniW7ZTqjNJvC79Ym7KowMYzCbmozzv
|
||||
3xqElA+g/MLFfxn52c/vl/obOVk5eBf3f7V68qKL2IDEip3fyZyoelhfTypq944m
|
||||
sSJFQjoVzgd7ykgouEwOceOT8YMWWigNsWl/hsVJ03Ri7TxRX4+v8dMEbat+SsTL
|
||||
AqTTgQ==
|
||||
-----END CERTIFICATE-----
|
17
test/recipes/65-test_cmp_vfy_data/server.crt
Normal file
17
test/recipes/65-test_cmp_vfy_data/server.crt
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu
|
||||
c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV
|
||||
BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj
|
||||
o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh
|
||||
BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd
|
||||
mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU
|
||||
shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd
|
||||
HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV
|
||||
WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY
|
||||
TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU
|
||||
A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy
|
||||
AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE
|
||||
T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9
|
||||
jQYqSl/ix5hn
|
||||
-----END CERTIFICATE-----
|
27
test/recipes/65-test_cmp_vfy_data/server.key
Normal file
27
test/recipes/65-test_cmp_vfy_data/server.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZA
|
||||
JHnq0ypW/PZccrWjo7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVV
|
||||
pLicMnItNFElfCohBzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuW
|
||||
q/vWW9r96/gBKKddmj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SO
|
||||
Zf9bH1olBVsmBMsUshFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6Gv
|
||||
Z/i5KOhaqgJCnRKdHHzijz9cLec5p9NSOuC1OwIDAQABAoIBAGiYVO+rIfqc38jG
|
||||
sMxJED2NSBFnvE7k2LoeEgktBA0daxQgziYXtIkOXC3jkwAw1RXLuGH5RTDuJt3/
|
||||
LX6nsCW3NCCB6lTGERNaJyKg4dLHpzA+juY3/2P/MKHD1bGncpV7jNk2fpV7gBY1
|
||||
pu0wld1Oi+S3DPCaxs3w6Zl39Y4Z7oSNf6DRO5lGN3Asc8TSVjIOWpAl8LIg+P2B
|
||||
ZvFeHRANVXaV9YmF2uEi7iMgH4vGrK2svsmM9VThVO4ArGcTRTvGYn7aw3/H4Pt+
|
||||
lYuhERdpkKBT0tCgIpO5IJXMl4/5RSDTtcBwiJcReN5IHUAItBIPSHcMflNSKG/I
|
||||
aQf4u0ECgYEA8+PAyzn096Y2UrKzE75yuadCveLjsUWx2NN5ZMohQru99F4k7Pab
|
||||
/Te4qOe5zlxHAPK3LRwvbwUWo5mLfs45wFrSgZoRlYcCuL+JaX0y2oXMMF9E+UkY
|
||||
tljMt/HpLo1SfSjN2Sae4LVhC7rWJ43LtyRepptzBPGqd26eLPGAMr8CgYEA7P8u
|
||||
RGkMOrMzEKAb0A9smrzq2xW88T1VejqEt6R8mUcNt8PFHMgjuzVU4zDysrlb7G/0
|
||||
VSkQWnJxBh1yNGc1Av7YgwicIgApr4ty0hZhLcnKX2VrNw+L/sSe/cnwVAc6RtPK
|
||||
RR6xQubuLlrCGcbYXmyn5Jv+nlY0S3uCyDFHqIUCgYAwtpLxhJf7RwWeqva9wNJl
|
||||
ZpUcHE9iPwtwxXx/tyfBjoI4Zv11HyS1BQYrJm2kXCYKeHBB4FlREXEeKDMGluZO
|
||||
F1XocP+GIDtY71jg6xLXNtY76yt5pzH6ae4p53WtyKhrO1UyRFaDh3bkwuK3b8j6
|
||||
wZbuLCpjGGn2BPAvBeWXPQKBgEewKN6op/pZmmi9Bay5/bAQ1TnQKYcPdnuyl9K0
|
||||
/ruespeTsFw0bhqC11qhw8gsKZIri0z3TusNEwM2hQU08uQlEnkQcaoXQoTHOcQy
|
||||
4NJo575Tf0r4ePBnqXA7VWcViJtEFTszPYtvLzz2VyBU9b4aP+73AN4EVW0/vx+v
|
||||
SG3BAoGBAMzESFA2TXwUFmozK5zowIszc995Xqpi7mXKk77WESOpoS1dQ1wF1dSg
|
||||
XOwxzFoYovLxcc1K9lqOrod8BV+qGuEfc/PIJ2aiXjvEDeZYX2eWaANNmj4OSLoJ
|
||||
MNYj9tZxbq56slD7snf7AgUBnwKz0Pj6H6UsbE3gdJqZWCDyw/bB
|
||||
-----END RSA PRIVATE KEY-----
|
@ -4928,3 +4928,10 @@ OSSL_HTTP_get_asn1 ? 3_0_0 EXIST::FUNCTION:SOCK
|
||||
OSSL_HTTP_post_asn1 ? 3_0_0 EXIST::FUNCTION:SOCK
|
||||
OSSL_HTTP_transfer ? 3_0_0 EXIST::FUNCTION:SOCK
|
||||
OSSL_HTTP_proxy_connect ? 3_0_0 EXIST::FUNCTION:SOCK
|
||||
ERR_add_error_txt ? 3_0_0 EXIST::FUNCTION:
|
||||
ERR_add_error_mem_bio ? 3_0_0 EXIST::FUNCTION:
|
||||
X509_STORE_CTX_print_verify_cb ? 3_0_0 EXIST::FUNCTION:
|
||||
X509_STORE_get1_all_certs ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_CMP_validate_msg ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_validate_cert_path ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_print_to_bio ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
|
Loading…
Reference in New Issue
Block a user