Skip to content

Commit

Permalink
Check that multi-strings/CHOICE types don't use implicit tagging
Browse files Browse the repository at this point in the history
It never makes sense for multi-string or CHOICE types to use implicit
tagging since the content would be ambiguous. It is an error in the
template if this ever happens. If we detect it we should stop parsing.

Thanks to David Benjamin from Google for reporting this issue.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
  • Loading branch information
mattcaswell committed Dec 8, 2020
1 parent f960d81 commit 1ecc76f
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 0 deletions.
1 change: 1 addition & 0 deletions crypto/asn1/asn1_err.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = {
"asn1 sig parse error"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_AUX_ERROR), "aux error"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_TEMPLATE), "bad template"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
"bmpstring is wrong length"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BN_LIB), "bn lib"},
Expand Down
19 changes: 19 additions & 0 deletions crypto/asn1/tasn_dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
tag, aclass, opt, ctx);

case ASN1_ITYPE_MSTRING:
/*
* It never makes sense for multi-strings to have implicit tagging, so
* if tag != -1, then this looks like an error in the template.
*/
if (tag != -1) {
ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_BAD_TEMPLATE);
goto err;
}

p = *in;
/* Just read in tag and class */
ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
Expand All @@ -199,6 +208,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
}

/* Check tag matches bit map */
if (!(ASN1_tag2bit(otag) & it->utype)) {
/* If OPTIONAL, assume this is OK */
Expand All @@ -215,6 +225,15 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);

case ASN1_ITYPE_CHOICE:
/*
* It never makes sense for CHOICE types to have implicit tagging, so
* if tag != -1, then this looks like an error in the template.
*/
if (tag != -1) {
ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_BAD_TEMPLATE);
goto err;
}

if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
if (*pval) {
Expand Down
1 change: 1 addition & 0 deletions crypto/err/openssl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,7 @@ ASN1_R_ASN1_PARSE_ERROR:203:asn1 parse error
ASN1_R_ASN1_SIG_PARSE_ERROR:204:asn1 sig parse error
ASN1_R_AUX_ERROR:100:aux error
ASN1_R_BAD_OBJECT_HEADER:102:bad object header
ASN1_R_BAD_TEMPLATE:230:bad template
ASN1_R_BMPSTRING_IS_WRONG_LENGTH:214:bmpstring is wrong length
ASN1_R_BN_LIB:105:bn lib
ASN1_R_BOOLEAN_IS_WRONG_LENGTH:106:boolean is wrong length
Expand Down
1 change: 1 addition & 0 deletions include/openssl/asn1err.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ int ERR_load_ASN1_strings(void);
# define ASN1_R_ASN1_SIG_PARSE_ERROR 204
# define ASN1_R_AUX_ERROR 100
# define ASN1_R_BAD_OBJECT_HEADER 102
# define ASN1_R_BAD_TEMPLATE 230
# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
# define ASN1_R_BN_LIB 105
# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
Expand Down

0 comments on commit 1ecc76f

Please sign in to comment.