summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2015-06-02 09:54:38 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2015-06-02 09:54:38 +0200
commitb09a79fa336eac47c95788d7fd1d6c2ee0eee2f5 (patch)
tree47a27200cec060b9e65f9e578868e9658fd5bf16
parentb3c88cf1a8d5271a45f96e5d608a9e3cf95204ac (diff)
downloadgnutls-b09a79fa336eac47c95788d7fd1d6c2ee0eee2f5.tar.gz
on PKCS #7 verification check the the content type matches the signed data
-rw-r--r--lib/x509/pkcs7.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index 94e36df6d6..3ebfb741da 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -572,6 +572,8 @@ static int verify_hash_attr(gnutls_pkcs7_t pkcs7, const char *root,
unsigned hash_size, i;
char oid[MAX_OID_SIZE];
char name[256];
+ unsigned msg_digest_ok = 0;
+ unsigned num_cont_types = 0;
int ret;
hash = gnutls_sign_get_hash_algorithm(algo);
@@ -607,18 +609,42 @@ static int verify_hash_attr(gnutls_pkcs7_t pkcs7, const char *root,
ret = _gnutls_x509_decode_and_read_attribute(pkcs7->signed_data,
name, oid, sizeof(oid), &tmp, 1, 0);
- if (ret < 0)
+ if (ret < 0) {
+ if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
+ break;
return gnutls_assert_val(ret);
+ }
if (strcmp(oid, ATTR_MESSAGE_DIGEST) == 0) {
ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
tmp.data, tmp.size, &tmp2, 0);
if (ret < 0) {
+ gnutls_assert();
goto cleanup;
}
if (tmp2.size == hash_size && memcmp(hash_output, tmp2.data, tmp2.size) == 0) {
- ret = 0;
+ msg_digest_ok = 1;
+ }
+ } else if (strcmp(oid, ATTR_CONTENT_TYPE) == 0) {
+ if (num_cont_types > 0) {
+ gnutls_assert();
+ ret = GNUTLS_E_PARSING_ERROR;
+ goto cleanup;
+ }
+
+ num_cont_types++;
+
+ /* check if it matches */
+ ret = _gnutls_x509_get_raw_field(pkcs7->signed_data, "encapContentInfo.eContentType", &tmp2);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ if (tmp2.size != tmp.size || memcmp(tmp.data, tmp2.data, tmp2.size) != 0) {
+ gnutls_assert();
+ ret = GNUTLS_E_PARSING_ERROR;
goto cleanup;
}
}
@@ -627,8 +653,11 @@ static int verify_hash_attr(gnutls_pkcs7_t pkcs7, const char *root,
gnutls_free(tmp2.data);
tmp2.data = NULL;
}
-
- /* FIXME: verify that content info matches */
+
+ if (msg_digest_ok)
+ ret = 0;
+ else
+ ret = gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
cleanup:
gnutls_free(tmp.data);