mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-10-28 18:07:34 +08:00
pkcs7: Add certificate chain verification and extended APIs
Extend PKCS#7 SignedData verification to support building and verifying the certificate chain of the signer. Add extended signature verification APIs that use caller-supplied trusted certificates and optionally embedded leaf certificates from the PKCS#7 structure. When embedded leaf certificates are used, their certificate chain is validated against the provided trusted CAs. Signed-off-by: Sridhar Markonda <sridharm@linux.ibm.com>
This commit is contained in:
parent
31cd11e04b
commit
89cc0b2cb4
@ -63,6 +63,8 @@
|
||||
#define MBEDTLS_ERR_PKCS7_ALLOC_FAILED PSA_ERROR_INSUFFICIENT_MEMORY /**< Allocation of memory failed. */
|
||||
#define MBEDTLS_ERR_PKCS7_VERIFY_FAIL PSA_ERROR_INVALID_SIGNATURE /**< Verification Failed */
|
||||
#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID -0x5880 /**< The PKCS #7 date issued/expired dates are invalid */
|
||||
#define MBEDTLS_ERR_PKCS7_CERT_VERIFY_FAILED -0x5900 /**< The PKCS #7 signer certificate verification failed. */
|
||||
#define MBEDTLS_ERR_PKCS7_SIGNER_CERT_NOT_FOUND -0x5980 /**< No certificate matching the PKCS#7 signer information was found. */
|
||||
/* \} name */
|
||||
|
||||
/**
|
||||
@ -208,7 +210,7 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
|
||||
*
|
||||
* \return 0 if the signature verifies, or a negative error code on failure.
|
||||
*/
|
||||
int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||
int mbedtls_pkcs7_signed_data_verify(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *data,
|
||||
size_t datalen);
|
||||
@ -240,10 +242,80 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||
*
|
||||
* \return 0 if the signature verifies, or a negative error code on failure.
|
||||
*/
|
||||
int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
int mbedtls_pkcs7_signed_hash_verify(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *hash, size_t hashlen);
|
||||
|
||||
/**
|
||||
* \brief Verify a PKCS #7 SignedData signature over plain data.
|
||||
*
|
||||
* For each signer in the PKCS#7 structure, this function verifies
|
||||
* the signature over the supplied data using the digest algorithm
|
||||
* specified by the signer and a matching leaf certificate.
|
||||
* Verification succeeds if at least one signer signature is valid.
|
||||
*
|
||||
* The verification uses certificates provided by the caller and,
|
||||
* optionally, certificates embedded within the PKCS#7 SignedData
|
||||
* structure. When certificates from the PKCS#7 structure are used,
|
||||
* the signer certificate chain is validated against the supplied
|
||||
* trusted certificates.
|
||||
*
|
||||
* \param pkcs7 PKCS#7 SignedData structure containing signatures.
|
||||
* \param trust_certs Certificate list containing trusted leaf and CA certificates.
|
||||
* CA certificates are used for certificate chain verification and
|
||||
* leaf certificates are used for signature verification.
|
||||
* \param data Plain data on which signature has to be verified.
|
||||
* \param datalen Length of the \p data.
|
||||
* \param use_pkcs7_leaf Flag indicating whether to use the leaf certificate embedded
|
||||
* in the PKCS#7 structure: set to \c 1 to enforce use of the PKCS#7
|
||||
* leaf certificate, or \c 0 to use only caller-supplied certificates.
|
||||
*
|
||||
* \note This function internally calculates the hash on the supplied
|
||||
* plain data for signature verification.
|
||||
*
|
||||
* \return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int mbedtls_pkcs7_signed_data_verify_ext(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *trust_certs,
|
||||
const unsigned char *data,
|
||||
const size_t datalen,
|
||||
const int use_pkcs7_leaf);
|
||||
|
||||
/**
|
||||
* \brief Verify PKCS #7 SignedData signature over a supplied hash.
|
||||
*
|
||||
* For each signer in the PKCS#7 structure, this function verifies
|
||||
* the signature over the supplied message hash using the digest
|
||||
* algorithm specified by the signer and a matching leaf certificate.
|
||||
* Verification succeeds if at least one signer signature is valid.
|
||||
*
|
||||
* The verification uses certificates provided by the caller and,
|
||||
* optionally, certificates embedded within the PKCS#7 SignedData
|
||||
* structure. When certificates from the PKCS#7 structure are used,
|
||||
* the signer certificate chain is validated against the supplied
|
||||
* trusted certificates.
|
||||
*
|
||||
* \param pkcs7 PKCS #7 SignedData structure containing signatures.
|
||||
* \param trust_certs Certificate list containing trusted leaf and CA certificates.
|
||||
* CA certificates are used for certificate chain verification and
|
||||
* leaf certificates are used for signature verification.
|
||||
* \param hash Hash of the plain data on which signature has to be verified.
|
||||
* \param hashlen Length of the \p hash.
|
||||
* \param use_pkcs7_leaf Flag indicating whether to use the leaf certificate embedded in
|
||||
* the PKCS#7 structure: set to \c 1 to enforce use of the PKCS#7
|
||||
* leaf certificate, or \c 0 to use only caller-supplied certificates.
|
||||
*
|
||||
* \note This function differs from mbedtls_pkcs7_signed_data_verify_ext()
|
||||
* in that the hash of the input data is provided directly by caller.
|
||||
*
|
||||
* \return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int mbedtls_pkcs7_signed_hash_verify_ext(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *trust_certs,
|
||||
const unsigned char *hash,
|
||||
const size_t hashlen,
|
||||
const int use_pkcs7_leaf);
|
||||
|
||||
/**
|
||||
* \brief Unallocate all PKCS #7 data and zeroize the memory.
|
||||
* It doesn't free \p pkcs7 itself. This should be done by the caller.
|
||||
|
||||
425
library/pkcs7.c
425
library/pkcs7.c
@ -697,20 +697,258 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *data,
|
||||
size_t datalen,
|
||||
const int is_data_hash)
|
||||
/**
|
||||
* \brief Decide whether a certificate should be classified as a CA.
|
||||
* Policy:
|
||||
* - If BasicConstraints present and CA=TRUE => CA
|
||||
* - If KeyUsage is present, require keyCertSign for CA
|
||||
* - If BasicConstraints absent => NOT a CA (classify as leaf)
|
||||
* - If BasicConstraints is present and CA=FALSE => not a CA (leaf)
|
||||
*
|
||||
* \param crt Certificate to classify.
|
||||
*
|
||||
* \return 1 if the certificate is classified as CA, 0 otherwise.
|
||||
*/
|
||||
static int pkcs7_is_ca_cert(const mbedtls_x509_crt *crt)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *hash;
|
||||
mbedtls_pk_context pk_cxt = cert->pk;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_pkcs7_signer_info *signer;
|
||||
/* BasicConstraints: is CA? */
|
||||
ret = mbedtls_x509_crt_get_ca_istrue(crt);
|
||||
if (ret == 1) {
|
||||
/* CA=TRUE; enforce keyCertSign only if KU exists */
|
||||
ret = mbedtls_x509_crt_check_key_usage(crt, MBEDTLS_X509_KU_KEY_CERT_SIGN);
|
||||
return (ret == 0) ? 1 : 0;
|
||||
} else {
|
||||
/* ret == 0: BC present, CA=FALSE. ret < 0: BasicConstraints absent) */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pkcs7->signed_data.no_of_signers == 0) {
|
||||
/**
|
||||
* \brief Check if the given CA certificate is a possible issuer of
|
||||
* the provided certificate.
|
||||
* \details This function attempts to match the issuer of \p cert with
|
||||
* the subject of \p ca using the following order:
|
||||
* 1. If both AKI keyIdentifier and SKI are present, compare them.
|
||||
* 2. If AKI authorityCertIssuer and authorityCertSerialNumber are
|
||||
* present, compare against the CA's subject DN and serial.
|
||||
* 3. Fallback to comparing issuer and subject Distinguished Name (DN).
|
||||
*
|
||||
* \param cert The certificate whose issuer is to be found.
|
||||
* \param ca Candidate CA certificate.
|
||||
*
|
||||
* \return 0 if \p ca is a potential issuer of \p cert, -1 otherwise.
|
||||
*/
|
||||
static int pkcs7_is_issuer_match(const mbedtls_x509_crt *cert,
|
||||
const mbedtls_x509_crt *ca)
|
||||
{
|
||||
if (cert->authority_key_id.keyIdentifier.len != 0 &&
|
||||
ca->subject_key_id.len != 0) {
|
||||
|
||||
if (cert->authority_key_id.keyIdentifier.len == ca->subject_key_id.len &&
|
||||
memcmp(cert->authority_key_id.keyIdentifier.p, ca->subject_key_id.p,
|
||||
ca->subject_key_id.len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cert->authority_key_id.authorityCertIssuer.buf.len != 0 &&
|
||||
cert->authority_key_id.authorityCertSerialNumber.len != 0) {
|
||||
|
||||
if (cert->authority_key_id.authorityCertIssuer.buf.len == ca->subject_raw.len &&
|
||||
memcmp(cert->authority_key_id.authorityCertIssuer.buf.p,
|
||||
ca->subject_raw.p, ca->subject_raw.len) == 0 &&
|
||||
cert->authority_key_id.authorityCertSerialNumber.len == ca->serial.len &&
|
||||
memcmp(cert->authority_key_id.authorityCertSerialNumber.p,
|
||||
ca->serial.p, ca->serial.len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cert->issuer_raw.len == ca->subject_raw.len &&
|
||||
memcmp(cert->issuer_raw.p, ca->subject_raw.p,
|
||||
cert->issuer_raw.len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if a certificate already exist in the chain
|
||||
* by comparing TBSCertificate content.
|
||||
*
|
||||
* \param chain The certificate chain to search
|
||||
* \param cert The certificate to look for
|
||||
*
|
||||
* \return 1 if certificate exists in chain
|
||||
* 0 if certificate does not exist
|
||||
*/
|
||||
static int pkcs7_is_duplicate_cert(const mbedtls_x509_crt *chain,
|
||||
const mbedtls_x509_crt *cert)
|
||||
{
|
||||
const mbedtls_x509_crt *cur;
|
||||
|
||||
for (cur = chain; cur != NULL; cur = cur->next) {
|
||||
if (cur->tbs.len != cert->tbs.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(cur->tbs.p, cert->tbs.p, cert->tbs.len) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build CA certificate chain from embedded PKCS#7 certs.
|
||||
*
|
||||
* \param pkcs7_certs Embedded certificate list (mbedtls_pkcs7_cert).
|
||||
* \param leaf_cert Leaf certificate to build chain for.
|
||||
* \param ca_chain On success, pointer to CA chain (caller must free).
|
||||
*
|
||||
* \return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
static int pkcs7_build_ca_chain(const mbedtls_pkcs7_cert *pkcs7_certs,
|
||||
const mbedtls_x509_crt *leaf_cert,
|
||||
mbedtls_x509_crt **ca_chain)
|
||||
{
|
||||
const mbedtls_x509_crt *current = leaf_cert;
|
||||
const mbedtls_pkcs7_cert *embedded_cert;
|
||||
mbedtls_x509_crt *chain = NULL;
|
||||
int ret;
|
||||
size_t depth = 0;
|
||||
|
||||
*ca_chain = NULL;
|
||||
|
||||
while (depth < MBEDTLS_X509_MAX_INTERMEDIATE_CA && current != NULL) {
|
||||
int found = 0;
|
||||
|
||||
for (embedded_cert = pkcs7_certs; embedded_cert != NULL;
|
||||
embedded_cert = embedded_cert->next) {
|
||||
const mbedtls_x509_crt *issuer = &embedded_cert->cert;
|
||||
|
||||
if (issuer->raw.p == NULL || issuer->raw.len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (issuer == current) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pkcs7_is_ca_cert(issuer) != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pkcs7_is_issuer_match(current, issuer) == 0) {
|
||||
if (pkcs7_is_duplicate_cert(chain, issuer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chain == NULL) {
|
||||
chain = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
|
||||
if (chain == NULL) {
|
||||
ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
mbedtls_x509_crt_init(chain);
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_crt_parse_der(chain, issuer->raw.p, issuer->raw.len);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
current = issuer;
|
||||
found = 1;
|
||||
depth++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*ca_chain = chain;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
if (chain != NULL) {
|
||||
mbedtls_x509_crt_free(chain);
|
||||
mbedtls_free(chain);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Verify certificate chain against trusted anchors.
|
||||
*
|
||||
* \details Builds CA chain from embedded PKCS#7 certs and verifies
|
||||
* the complete chain against trust anchors.
|
||||
*
|
||||
* \note mbedtls_x509_crt_verify() accepts mixed list of trusted
|
||||
* CAs and trusted leaf certs.
|
||||
*
|
||||
* \param pkcs7_certs Embedded certificate list
|
||||
* \param leaf_cert Leaf certificate to verify.
|
||||
* \param trust_anchors Trust anchors: root CAs and/or trusted leaf certs.
|
||||
*
|
||||
* \return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
static int pkcs7_verify_chain(const mbedtls_pkcs7_cert *pkcs7_certs,
|
||||
mbedtls_x509_crt *leaf_cert,
|
||||
const mbedtls_x509_crt *trust_anchors)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_x509_crt *ca_chain = NULL;
|
||||
uint32_t flags = 0;
|
||||
|
||||
ret = pkcs7_build_ca_chain(pkcs7_certs, leaf_cert, &ca_chain);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
leaf_cert->next = ca_chain;
|
||||
ret = mbedtls_x509_crt_verify(leaf_cert, (mbedtls_x509_crt *) trust_anchors,
|
||||
NULL, NULL, &flags, NULL, NULL);
|
||||
|
||||
leaf_cert->next = NULL;
|
||||
|
||||
if (ca_chain != NULL) {
|
||||
mbedtls_x509_crt_free(ca_chain);
|
||||
mbedtls_free(ca_chain);
|
||||
}
|
||||
|
||||
if (ret != 0 || flags != 0) {
|
||||
return MBEDTLS_ERR_PKCS7_CERT_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if certificate matches signer info.
|
||||
*
|
||||
* \details Validates certificate date, matches serial/issuer,
|
||||
* and checks key usage for digital signature.
|
||||
*
|
||||
* \param cert Certificate to check.
|
||||
* \param signer Signer info to match against.
|
||||
*
|
||||
* \return 0 if match, or a negative error code otherwise.
|
||||
*/
|
||||
static int pkcs7_check_cert_with_signer(const mbedtls_x509_crt *cert,
|
||||
const mbedtls_pkcs7_signer_info *signer)
|
||||
{
|
||||
if (cert->raw.p == NULL || cert->raw.len == 0) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_CERT;
|
||||
}
|
||||
|
||||
@ -719,6 +957,96 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
|
||||
}
|
||||
|
||||
if (cert->serial.len != signer->serial.len ||
|
||||
memcmp(cert->serial.p, signer->serial.p, signer->serial.len) != 0) {
|
||||
return MBEDTLS_ERR_PKCS7_SIGNER_CERT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (cert->issuer_raw.len != signer->issuer_raw.len ||
|
||||
memcmp(cert->issuer_raw.p, signer->issuer_raw.p,
|
||||
signer->issuer_raw.len) != 0) {
|
||||
return MBEDTLS_ERR_PKCS7_SIGNER_CERT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (mbedtls_x509_crt_check_key_usage(cert,
|
||||
MBEDTLS_X509_KU_DIGITAL_SIGNATURE) != 0) {
|
||||
return MBEDTLS_ERR_PKCS7_SIGNER_CERT_NOT_FOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Find matching leaf certificate.
|
||||
*
|
||||
* \details Searches for certificate matching signer info.
|
||||
* Can search in embedded PKCS#7 certs or external chain.
|
||||
*
|
||||
* \param pkcs7 PKCS#7 structure (for embedded certs).
|
||||
* \param certs External certificate chain.
|
||||
* \param signer Signer info to match against.
|
||||
* \param use_pkcs7_leaf Flag: 1=search embedded, 0=search external.
|
||||
* \param leaf_cert On success, pointer to matching certificate.
|
||||
*
|
||||
* \return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
static int pkcs7_get_leaf_cert(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *certs,
|
||||
const mbedtls_pkcs7_signer_info *signer,
|
||||
const int use_pkcs7_leaf,
|
||||
mbedtls_x509_crt **leaf_cert)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_PKCS7_SIGNER_CERT_NOT_FOUND;
|
||||
|
||||
if (use_pkcs7_leaf == 1) {
|
||||
const mbedtls_pkcs7_cert *embedded_cert = pkcs7->signed_data.certs;
|
||||
|
||||
while (embedded_cert != NULL) {
|
||||
const mbedtls_x509_crt *cert = &embedded_cert->cert;
|
||||
|
||||
ret = pkcs7_check_cert_with_signer(cert, signer);
|
||||
if (ret == 0) {
|
||||
*leaf_cert = (mbedtls_x509_crt *) cert;
|
||||
return 0;
|
||||
}
|
||||
|
||||
embedded_cert = embedded_cert->next;
|
||||
}
|
||||
} else {
|
||||
const mbedtls_x509_crt *cert = certs;
|
||||
|
||||
while (cert != NULL) {
|
||||
ret = pkcs7_check_cert_with_signer(cert, signer);
|
||||
if (ret == 0) {
|
||||
*leaf_cert = (mbedtls_x509_crt *) cert;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cert = cert->next;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbedtls_pkcs7_data_or_hash_verify(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *data,
|
||||
size_t datalen,
|
||||
const int is_data_hash,
|
||||
const int use_pkcs7_leaf)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *hash = NULL;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_type_t md_alg;
|
||||
const mbedtls_pkcs7_signer_info *signer;
|
||||
mbedtls_x509_crt *leaf_cert = NULL;
|
||||
|
||||
if (pkcs7->signed_data.no_of_signers == 0) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_CERT;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
@ -764,21 +1092,26 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
/* assume failure */
|
||||
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
|
||||
|
||||
/*
|
||||
* Potential TODOs
|
||||
* Currently we iterate over all signers and return success if any of them
|
||||
* verify.
|
||||
*
|
||||
* However, we could make this better by checking against the certificate's
|
||||
* identification and SignerIdentifier fields first. That would also allow
|
||||
* us to distinguish between 'no signature for key' and 'signature for key
|
||||
* failed to validate'.
|
||||
*/
|
||||
for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
|
||||
ret = mbedtls_pk_verify_ext(cert->sig_pk, &pk_cxt, md_alg, hash,
|
||||
mbedtls_md_get_size(md_info),
|
||||
signer->sig.p, signer->sig.len);
|
||||
if (signer->sig.p == NULL || signer->sig.len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = pkcs7_get_leaf_cert(pkcs7, cert, signer, use_pkcs7_leaf, &leaf_cert);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (use_pkcs7_leaf == 1) {
|
||||
ret = pkcs7_verify_chain(pkcs7->signed_data.certs, leaf_cert, cert);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_pk_verify_ext(leaf_cert->sig_pk, &leaf_cert->pk, md_alg,
|
||||
hash, mbedtls_md_get_size(md_info),
|
||||
signer->sig.p, signer->sig.len);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
@ -789,26 +1122,58 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||
int mbedtls_pkcs7_signed_data_verify(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *data,
|
||||
size_t datalen)
|
||||
{
|
||||
if (data == NULL) {
|
||||
if (data == NULL || pkcs7 == NULL || cert == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
|
||||
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0, 0);
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
int mbedtls_pkcs7_signed_hash_verify(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *hash,
|
||||
size_t hashlen)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
if (hash == NULL || pkcs7 == NULL || cert == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
|
||||
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1, 0);
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_signed_data_verify_ext(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *trust_certs,
|
||||
const unsigned char *data,
|
||||
const size_t datalen,
|
||||
const int use_pkcs7_leaf)
|
||||
{
|
||||
if (data == NULL || pkcs7 == NULL || trust_certs == NULL ||
|
||||
(use_pkcs7_leaf != 0 && use_pkcs7_leaf != 1)) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, trust_certs, data, datalen,
|
||||
0, use_pkcs7_leaf);
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_signed_hash_verify_ext(const mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *trust_certs,
|
||||
const unsigned char *hash,
|
||||
const size_t hashlen,
|
||||
const int use_pkcs7_leaf)
|
||||
{
|
||||
if (hash == NULL || pkcs7 == NULL || trust_certs == NULL ||
|
||||
(use_pkcs7_leaf != 0 && use_pkcs7_leaf != 1)) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, trust_certs, hash, hashlen,
|
||||
1, use_pkcs7_leaf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user