pkcs7: reject signatures with internal data
A CMS signature can have internal data, but mbedTLS does not support verifying such signatures. Reject them during parsing. Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
This commit is contained in:
parent
e373a254c4
commit
6cfc469296
2 changed files with 28 additions and 28 deletions
|
@ -135,21 +135,12 @@ typedef struct mbedtls_pkcs7_signer_info {
|
||||||
}
|
}
|
||||||
mbedtls_pkcs7_signer_info;
|
mbedtls_pkcs7_signer_info;
|
||||||
|
|
||||||
/**
|
|
||||||
* Structure holding attached data as part of PKCS7 signed data format
|
|
||||||
*/
|
|
||||||
typedef struct mbedtls_pkcs7_data {
|
|
||||||
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(data);
|
|
||||||
}
|
|
||||||
mbedtls_pkcs7_data;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure holding the signed data section
|
* Structure holding the signed data section
|
||||||
*/
|
*/
|
||||||
typedef struct mbedtls_pkcs7_signed_data {
|
typedef struct mbedtls_pkcs7_signed_data {
|
||||||
int MBEDTLS_PRIVATE(version);
|
int MBEDTLS_PRIVATE(version);
|
||||||
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(digest_alg_identifiers);
|
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(digest_alg_identifiers);
|
||||||
struct mbedtls_pkcs7_data MBEDTLS_PRIVATE(content);
|
|
||||||
int MBEDTLS_PRIVATE(no_of_certs);
|
int MBEDTLS_PRIVATE(no_of_certs);
|
||||||
mbedtls_x509_crt MBEDTLS_PRIVATE(certs);
|
mbedtls_x509_crt MBEDTLS_PRIVATE(certs);
|
||||||
int MBEDTLS_PRIVATE(no_of_crls);
|
int MBEDTLS_PRIVATE(no_of_crls);
|
||||||
|
@ -176,7 +167,7 @@ mbedtls_pkcs7;
|
||||||
void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7);
|
void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Parse a single DER formatted pkcs7 content.
|
* \brief Parse a single DER formatted pkcs7 detached signature.
|
||||||
*
|
*
|
||||||
* \param pkcs7 The pkcs7 structure to be filled by parser for the output.
|
* \param pkcs7 The pkcs7 structure to be filled by parser for the output.
|
||||||
* \param buf The buffer holding only the DER encoded pkcs7.
|
* \param buf The buffer holding only the DER encoded pkcs7.
|
||||||
|
@ -186,6 +177,7 @@ void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7);
|
||||||
* \note This function makes an internal copy of the PKCS7 buffer
|
* \note This function makes an internal copy of the PKCS7 buffer
|
||||||
* \p buf. In particular, \p buf may be destroyed or reused
|
* \p buf. In particular, \p buf may be destroyed or reused
|
||||||
* after this call returns.
|
* after this call returns.
|
||||||
|
* \note Signatures with internal data are not supported.
|
||||||
*
|
*
|
||||||
* \return The \c mbedtls_pkcs7_type of \p buf, if successful.
|
* \return The \c mbedtls_pkcs7_type of \p buf, if successful.
|
||||||
* \return A negative error code on failure.
|
* \return A negative error code on failure.
|
||||||
|
@ -205,7 +197,8 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
|
||||||
* matches.
|
* matches.
|
||||||
*
|
*
|
||||||
* This function does not use the certificates held within the
|
* This function does not use the certificates held within the
|
||||||
* PKCS7 structure itself.
|
* PKCS7 structure itself, and does not check that the
|
||||||
|
* certificate is signed by a trusted certification authority.
|
||||||
*
|
*
|
||||||
* \param pkcs7 PKCS7 structure containing signature.
|
* \param pkcs7 PKCS7 structure containing signature.
|
||||||
* \param cert Certificate containing key to verify signature.
|
* \param cert Certificate containing key to verify signature.
|
||||||
|
@ -226,15 +219,15 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||||
* \brief Verification of PKCS7 signature against a caller-supplied
|
* \brief Verification of PKCS7 signature against a caller-supplied
|
||||||
* certificate.
|
* certificate.
|
||||||
*
|
*
|
||||||
* For each signer in the PKCS structure, this function computes
|
* For each signer in the PKCS structure, this function
|
||||||
* a signature over the supplied hash, using the supplied
|
* validates a signature over the supplied hash, using the
|
||||||
* certificate and the same digest algorithm as specified by the
|
* supplied certificate and the same digest algorithm as
|
||||||
* signer. It then compares this signature against the
|
* specified by the signer. Verification succeeds if any
|
||||||
* signer's signature; verification succeeds if any comparison
|
* signature is good.
|
||||||
* matches.
|
|
||||||
*
|
*
|
||||||
* This function does not use the certificates held within the
|
* This function does not use the certificates held within the
|
||||||
* PKCS7 structure itself.
|
* PKCS7 structure itself, and does not check that the
|
||||||
|
* certificate is signed by a trusted certification authority.
|
||||||
*
|
*
|
||||||
* \param pkcs7 PKCS7 structure containing signature.
|
* \param pkcs7 PKCS7 structure containing signature.
|
||||||
* \param cert Certificate containing key to verify signature.
|
* \param cert Certificate containing key to verify signature.
|
||||||
|
@ -242,7 +235,7 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||||
* \param hashlen Length of the hash.
|
* \param hashlen Length of the hash.
|
||||||
*
|
*
|
||||||
* \note This function is different from mbedtls_pkcs7_signed_data_verify()
|
* \note This function is different from mbedtls_pkcs7_signed_data_verify()
|
||||||
* in a way that it directly receives the hash of the data.
|
* in that it is directly passed the hash of the data.
|
||||||
*
|
*
|
||||||
* \return 0 if the signature verifies, or a negative error code on failure.
|
* \return 0 if the signature verifies, or a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -57,9 +57,9 @@ static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
|
||||||
ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
|
ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
|
||||||
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
|
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
|
||||||
} else if ((size_t) (end - *p) != *len) {
|
} else if ((size_t) (end - *p) != *len) {
|
||||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
|
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
|
||||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,13 +187,13 @@ static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
|
||||||
size_t len2 = 0;
|
size_t len2 = 0;
|
||||||
unsigned char *end_set, *end_cert, *start;
|
unsigned char *end_set, *end_cert, *start;
|
||||||
|
|
||||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
|
ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
|
||||||
| MBEDTLS_ASN1_CONTEXT_SPECIFIC)) != 0) {
|
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
||||||
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
|
|
||||||
}
|
}
|
||||||
|
if (ret != 0) {
|
||||||
|
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
|
||||||
}
|
}
|
||||||
start = *p;
|
start = *p;
|
||||||
end_set = *p + len1;
|
end_set = *p + len1;
|
||||||
|
@ -716,11 +716,15 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||||
const mbedtls_x509_crt *cert,
|
const mbedtls_x509_crt *cert,
|
||||||
const unsigned char *data,
|
const unsigned char *data,
|
||||||
size_t datalen)
|
size_t datalen)
|
||||||
{
|
{
|
||||||
|
if (data == 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,6 +733,9 @@ int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||||
const unsigned char *hash,
|
const unsigned char *hash,
|
||||||
size_t hashlen)
|
size_t hashlen)
|
||||||
{
|
{
|
||||||
|
if (hash == 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue