PR: 2696
Submitted by: Rob Austein <sra@hactrn.net> Fix inverted range problem in RFC3779 code. Thanks to Andrew Chi for generating test cases for this bug.
This commit is contained in:
parent
6ca7dba0cf
commit
b26297ca51
@ -358,6 +358,20 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for inverted range.
|
||||||
|
*/
|
||||||
|
i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
|
||||||
|
{
|
||||||
|
ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
|
||||||
|
ASN1_INTEGER *a_min, *a_max;
|
||||||
|
if (a != NULL && a->type == ASIdOrRange_range) {
|
||||||
|
extract_min_max(a, &a_min, &a_max);
|
||||||
|
if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -392,9 +406,18 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have a list. Sort it.
|
* If not a list, or if empty list, it's broken.
|
||||||
|
*/
|
||||||
|
if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
|
||||||
|
sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
|
||||||
|
X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
|
||||||
|
X509V3_R_EXTENSION_VALUE_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have a non-empty list. Sort it.
|
||||||
*/
|
*/
|
||||||
OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
|
|
||||||
sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
|
sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -414,6 +437,13 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
|
|||||||
*/
|
*/
|
||||||
OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
|
OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Punt inverted ranges.
|
||||||
|
*/
|
||||||
|
if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
|
||||||
|
ASN1_INTEGER_cmp(b_min, b_max) > 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for overlaps.
|
* Check for overlaps.
|
||||||
*/
|
*/
|
||||||
@ -465,12 +495,26 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ASIdOrRange_free(b);
|
ASIdOrRange_free(b);
|
||||||
sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
|
(void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for final inverted range.
|
||||||
|
*/
|
||||||
|
i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
|
||||||
|
{
|
||||||
|
ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
|
||||||
|
ASN1_INTEGER *a_min, *a_max;
|
||||||
|
if (a != NULL && a->type == ASIdOrRange_range) {
|
||||||
|
extract_min_max(a, &a_min, &a_max);
|
||||||
|
if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
|
OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -498,6 +542,7 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
|
|||||||
struct v3_ext_ctx *ctx,
|
struct v3_ext_ctx *ctx,
|
||||||
STACK_OF(CONF_VALUE) *values)
|
STACK_OF(CONF_VALUE) *values)
|
||||||
{
|
{
|
||||||
|
ASN1_INTEGER *min = NULL, *max = NULL;
|
||||||
ASIdentifiers *asid = NULL;
|
ASIdentifiers *asid = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -508,7 +553,6 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
|
|||||||
|
|
||||||
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||||
CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
|
CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
|
||||||
ASN1_INTEGER *min = NULL, *max = NULL;
|
|
||||||
int i1, i2, i3, is_range, which;
|
int i1, i2, i3, is_range, which;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -578,18 +622,19 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
|
|||||||
max = s2i_ASN1_INTEGER(NULL, s + i2);
|
max = s2i_ASN1_INTEGER(NULL, s + i2);
|
||||||
OPENSSL_free(s);
|
OPENSSL_free(s);
|
||||||
if (min == NULL || max == NULL) {
|
if (min == NULL || max == NULL) {
|
||||||
ASN1_INTEGER_free(min);
|
|
||||||
ASN1_INTEGER_free(max);
|
|
||||||
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
|
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (ASN1_INTEGER_cmp(min, max) > 0) {
|
||||||
|
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!v3_asid_add_id_or_range(asid, which, min, max)) {
|
if (!v3_asid_add_id_or_range(asid, which, min, max)) {
|
||||||
ASN1_INTEGER_free(min);
|
|
||||||
ASN1_INTEGER_free(max);
|
|
||||||
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
|
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
min = max = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -601,6 +646,8 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
ASIdentifiers_free(asid);
|
ASIdentifiers_free(asid);
|
||||||
|
ASN1_INTEGER_free(min);
|
||||||
|
ASN1_INTEGER_free(max);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user