Skip to content

Commit 8a104a9

Browse files
pkcs7: parse authenticated attributes
Signed-off-by: Jean-Baptiste Boric <[email protected]>
1 parent 24ca2d4 commit 8a104a9

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

include/mbedtls/pkcs7.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ typedef enum {
102102
}
103103
mbedtls_pkcs7_type;
104104

105+
/**
106+
* Structure holding PKCS #7 authenticated attributes
107+
*/
108+
typedef struct mbedtls_pkcs7_auth_attributes {
109+
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(message_digest_raw);
110+
}
111+
mbedtls_pkcs7_auth_attributes;
112+
105113
/**
106114
* Structure holding PKCS #7 signer info
107115
*/
@@ -110,6 +118,8 @@ typedef struct mbedtls_pkcs7_signer_info {
110118
mbedtls_x509_buf MBEDTLS_PRIVATE(serial);
111119
mbedtls_x509_name MBEDTLS_PRIVATE(issuer);
112120
mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw);
121+
struct mbedtls_pkcs7_auth_attributes MBEDTLS_PRIVATE(auth_attributes);
122+
mbedtls_x509_buf MBEDTLS_PRIVATE(auth_attributes_raw);
113123
mbedtls_x509_buf MBEDTLS_PRIVATE(alg_identifier);
114124
mbedtls_x509_buf MBEDTLS_PRIVATE(sig_alg_identifier);
115125
mbedtls_x509_buf MBEDTLS_PRIVATE(sig);

library/pkcs7.c

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,97 @@ static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
247247
signer->issuer.next = NULL;
248248
}
249249

250+
static int pkcs7_get_authenticated_attributes(unsigned char **p, unsigned char *end_signer,
251+
mbedtls_pkcs7_signer_info *signer)
252+
{
253+
int ret;
254+
unsigned char *end;
255+
unsigned char *start_attr;
256+
unsigned char *start_attr_type;
257+
unsigned char *end_attr_value;
258+
size_t attr_len;
259+
size_t attr_type_len;
260+
size_t attr_value_len;
261+
size_t len;
262+
int seen_content_type = 0;
263+
int seen_message_digest = 0;
264+
265+
ret = mbedtls_asn1_get_tag(p, end_signer, &signer->auth_attributes_raw.len,
266+
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0);
267+
if (ret == 0) {
268+
/*
269+
* Per RFC 2315 Section 9.3, if the authenticatedAttributes field is present, the
270+
* message digest is computed on the DER encoding of the Attributes value.
271+
* Canonically, the authenticatedAttributes tag would therefore be encoded as SET OF.
272+
*/
273+
signer->auth_attributes_raw.tag = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET;
274+
signer->auth_attributes_raw.p = *p;
275+
end = *p + signer->auth_attributes_raw.len;
276+
277+
while (*p != end) {
278+
if ((ret = mbedtls_asn1_get_tag(p, end, &attr_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
279+
return ret;
280+
}
281+
start_attr = *p;
282+
283+
if ((ret = mbedtls_asn1_get_tag(p, end, &attr_type_len, MBEDTLS_ASN1_OID)) != 0) {
284+
return ret;
285+
}
286+
start_attr_type = *p;
287+
*p += attr_type_len;
288+
289+
if ((ret = mbedtls_asn1_get_tag(p, end, &attr_value_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
290+
return ret;
291+
}
292+
end_attr_value = *p + attr_value_len;
293+
294+
if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_CONTENT_TYPE, start_attr_type, attr_type_len)) {
295+
if ((ret = mbedtls_asn1_get_tag(p, end_attr_value, &len, MBEDTLS_ASN1_OID)) != 0) {
296+
return ret;
297+
}
298+
299+
if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, *p, len)) {
300+
return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
301+
}
302+
303+
*p += len;
304+
305+
if (*p != end_attr_value) {
306+
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
307+
}
308+
309+
seen_content_type = 1;
310+
} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_MESSAGE_DIGEST, start_attr_type, attr_type_len)) {
311+
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
312+
return ret;
313+
}
314+
315+
signer->auth_attributes.message_digest_raw.tag = MBEDTLS_ASN1_OCTET_STRING;
316+
signer->auth_attributes.message_digest_raw.len = len;
317+
signer->auth_attributes.message_digest_raw.p = *p;
318+
319+
*p += len;
320+
321+
if (*p != end_attr_value) {
322+
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
323+
}
324+
325+
seen_message_digest = 1;
326+
} else {
327+
/* Unknown attribute type, skip attribute. */
328+
*p = start_attr + attr_len;
329+
}
330+
}
331+
332+
if (!seen_content_type || !seen_message_digest) {
333+
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
334+
}
335+
}
336+
337+
/* authenticatedAttributes are optional, don't fail if it's not present. */
338+
return 0;
339+
}
340+
250341
/**
251342
* SignerInfo ::= SEQUENCE {
252343
* version Version;
@@ -260,8 +351,7 @@ static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
260351
* [1] IMPLICIT Attributes OPTIONAL,
261352
* Returns 0 if the signerInfo is valid.
262353
* Return negative error code for failure.
263-
* Structure must not contain vales for authenticatedAttributes
264-
* and unauthenticatedAttributes.
354+
* Structure must not contain values for unauthenticatedAttributes.
265355
**/
266356
static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
267357
mbedtls_pkcs7_signer_info *signer,
@@ -331,7 +421,11 @@ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
331421
goto out;
332422
}
333423

334-
/* Assume authenticatedAttributes is nonexistent */
424+
ret = pkcs7_get_authenticated_attributes(p, end_signer, signer);
425+
if (ret != 0) {
426+
goto out;
427+
}
428+
335429
ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
336430
if (ret != 0) {
337431
goto out;

0 commit comments

Comments
 (0)