Skip to content

Commit d93853c

Browse files
Viktor Dukhovnit8m
authored andcommitted
Avoid length truncation in ASN1_STRING_set
The ASN1_STRING_set() function takes an `int` length, make sure the argument is not inadvertently truncated when it is called from asn1_ex_c2i(). Fixes CVE-2026-34180 Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org> Reviewed-by: Norbert Pocs <norbertp@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.foundation> MergeDate: Mon Jun 8 14:13:56 2026 (cherry picked from commit 5f525cace61a53311ee533374919356c700847d9)
1 parent 5f54bfc commit d93853c

1 file changed

Lines changed: 17 additions & 7 deletions

File tree

‎crypto/asn1/tasn_dec.c‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
5454
const ASN1_ITEM *it,
5555
int tag, int aclass, char opt,
5656
ASN1_TLC *ctx);
57-
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
57+
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
5858
int utype, char *free_cont, const ASN1_ITEM *it);
5959

6060
/* Table to convert tags to bit values, used for MSTRING type */
@@ -855,19 +855,24 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
855855

856856
/* Translate ASN1 content octets into a structure */
857857

858-
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
858+
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
859859
int utype, char *free_cont, const ASN1_ITEM *it)
860860
{
861861
ASN1_VALUE **opval = NULL;
862862
ASN1_STRING *stmp;
863863
ASN1_TYPE *typ = NULL;
864864
int ret = 0;
865+
int ilen = (int)len;
865866
const ASN1_PRIMITIVE_FUNCS *pf;
866867
ASN1_INTEGER **tint;
867868
pf = it->funcs;
868869

869-
if (pf && pf->prim_c2i)
870-
return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
870+
if (pf && pf->prim_c2i) {
871+
if (len == (long)ilen)
872+
return pf->prim_c2i(pval, cont, ilen, utype, free_cont, it);
873+
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
874+
return 0;
875+
}
871876
/* If ANY type clear type and set pointer to internal value */
872877
if (it->utype == V_ASN1_ANY) {
873878
if (*pval == NULL) {
@@ -885,7 +890,8 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
885890
}
886891
switch (utype) {
887892
case V_ASN1_OBJECT:
888-
if (!ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
893+
if (len != (long)ilen
894+
|| !ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, ilen))
889895
goto err;
890896
break;
891897

@@ -940,6 +946,10 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
940946
case V_ASN1_SET:
941947
case V_ASN1_SEQUENCE:
942948
default:
949+
if (len != (long)ilen) {
950+
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
951+
goto err;
952+
}
943953
if (utype == V_ASN1_BMPSTRING && (len & 1)) {
944954
ERR_raise(ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
945955
goto err;
@@ -970,10 +980,10 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
970980
}
971981
/* If we've already allocated a buffer use it */
972982
if (*free_cont) {
973-
ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, len);
983+
ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, ilen);
974984
*free_cont = 0;
975985
} else {
976-
if (!ASN1_STRING_set(stmp, cont, len)) {
986+
if (!ASN1_STRING_set(stmp, cont, ilen)) {
977987
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
978988
ASN1_STRING_free(stmp);
979989
*pval = NULL;

0 commit comments

Comments
 (0)