mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-20 21:49:28 +00:00
feat(real-world-vfc-slice): add labeled OpenSSL/Firefox/Chromium/curl pair corpus
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows) into benchmarks/pairs/vfc with provenance and a JSONL training manifest. Score the slice as an honesty dashboard (ousast pairs --slice vfc); keep the pair gate on the local fixtures only.
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
/* Provenance: openssl/openssl do_x509_check (fixed).
|
||||
* repo: openssl/openssl
|
||||
* commit: 06d1dc3fa96a2ba5a3e22735a033012aadc9f0d6
|
||||
* parent: 9aae56395aa8e77c44a9df83fd395a644d016635
|
||||
* commit_url: https://github.com/openssl/openssl/commit/06d1dc3fa96a2ba5a3e22735a033012aadc9f0d6
|
||||
* cve: CVE-2024-6119
|
||||
* license: Apache-2.0
|
||||
* function: do_x509_check
|
||||
* relpath: crypto/x509/v3_utl.c
|
||||
*/
|
||||
|
||||
static int do_x509_check(X509 *x, const char *chk, size_t chklen,
|
||||
unsigned int flags, int check_type, char **peername)
|
||||
{
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
const X509_NAME *name = NULL;
|
||||
int i;
|
||||
int cnid = NID_undef;
|
||||
int alt_type;
|
||||
int san_present = 0;
|
||||
int rv = 0;
|
||||
equal_fn equal;
|
||||
|
||||
/* See below, this flag is internal-only */
|
||||
flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
|
||||
if (check_type == GEN_EMAIL) {
|
||||
cnid = NID_pkcs9_emailAddress;
|
||||
alt_type = V_ASN1_IA5STRING;
|
||||
equal = equal_email;
|
||||
} else if (check_type == GEN_DNS) {
|
||||
cnid = NID_commonName;
|
||||
/* Implicit client-side DNS sub-domain pattern */
|
||||
if (chklen > 1 && chk[0] == '.')
|
||||
flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
|
||||
alt_type = V_ASN1_IA5STRING;
|
||||
if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
|
||||
equal = equal_nocase;
|
||||
else
|
||||
equal = equal_wildcard;
|
||||
} else {
|
||||
alt_type = V_ASN1_OCTET_STRING;
|
||||
equal = equal_case;
|
||||
}
|
||||
|
||||
if (chklen == 0)
|
||||
chklen = strlen(chk);
|
||||
|
||||
gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
|
||||
if (gens) {
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
|
||||
GENERAL_NAME *gen;
|
||||
ASN1_STRING *cstr;
|
||||
|
||||
gen = sk_GENERAL_NAME_value(gens, i);
|
||||
switch (gen->type) {
|
||||
default:
|
||||
continue;
|
||||
case GEN_OTHERNAME:
|
||||
switch (OBJ_obj2nid(gen->d.otherName->type_id)) {
|
||||
default:
|
||||
continue;
|
||||
case NID_id_on_SmtpUTF8Mailbox:
|
||||
/*-
|
||||
* https://datatracker.ietf.org/doc/html/rfc8398#section-3
|
||||
*
|
||||
* Due to name constraint compatibility reasons described
|
||||
* in Section 6, SmtpUTF8Mailbox subjectAltName MUST NOT
|
||||
* be used unless the local-part of the email address
|
||||
* contains non-ASCII characters. When the local-part is
|
||||
* ASCII, rfc822Name subjectAltName MUST be used instead
|
||||
* of SmtpUTF8Mailbox. This is compatible with legacy
|
||||
* software that supports only rfc822Name (and not
|
||||
* SmtpUTF8Mailbox). [...]
|
||||
*
|
||||
* SmtpUTF8Mailbox is encoded as UTF8String.
|
||||
*
|
||||
* If it is not a UTF8String then that is unexpected, and
|
||||
* we ignore the invalid SAN (neither set san_present nor
|
||||
* consider it a candidate for equality). This does mean
|
||||
* that the subject CN may be considered, as would be the
|
||||
* case when the malformed SmtpUtf8Mailbox SAN is instead
|
||||
* simply absent.
|
||||
*
|
||||
* When CN-ID matching is not desirable, applications can
|
||||
* choose to turn it off, doing so is at this time a best
|
||||
* practice.
|
||||
*/
|
||||
if (check_type != GEN_EMAIL
|
||||
|| gen->d.otherName->value->type != V_ASN1_UTF8STRING)
|
||||
continue;
|
||||
alt_type = 0;
|
||||
cstr = gen->d.otherName->value->value.utf8string;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GEN_EMAIL:
|
||||
if (check_type != GEN_EMAIL)
|
||||
continue;
|
||||
cstr = gen->d.rfc822Name;
|
||||
break;
|
||||
case GEN_DNS:
|
||||
if (check_type != GEN_DNS)
|
||||
continue;
|
||||
cstr = gen->d.dNSName;
|
||||
break;
|
||||
case GEN_IPADD:
|
||||
if (check_type != GEN_IPADD)
|
||||
continue;
|
||||
cstr = gen->d.iPAddress;
|
||||
break;
|
||||
}
|
||||
san_present = 1;
|
||||
/* Positive on success, negative on error! */
|
||||
if ((rv = do_check_string(cstr, alt_type, equal, flags,
|
||||
chk, chklen, peername)) != 0)
|
||||
break;
|
||||
}
|
||||
GENERAL_NAMES_free(gens);
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We're done if CN-ID is not pertinent */
|
||||
if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT))
|
||||
return 0;
|
||||
|
||||
i = -1;
|
||||
name = X509_get_subject_name(x);
|
||||
while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
|
||||
const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
|
||||
const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne);
|
||||
|
||||
/* Positive on success, negative on error! */
|
||||
if ((rv = do_check_string(str, -1, equal, flags,
|
||||
chk, chklen, peername)) != 0)
|
||||
return rv;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/* Provenance: openssl/openssl do_x509_check (vuln).
|
||||
* repo: openssl/openssl
|
||||
* commit: 9aae56395aa8e77c44a9df83fd395a644d016635
|
||||
* parent: 9aae56395aa8e77c44a9df83fd395a644d016635
|
||||
* commit_url: https://github.com/openssl/openssl/commit/06d1dc3fa96a2ba5a3e22735a033012aadc9f0d6
|
||||
* cve: CVE-2024-6119
|
||||
* license: Apache-2.0
|
||||
* function: do_x509_check
|
||||
* relpath: crypto/x509/v3_utl.c
|
||||
*/
|
||||
|
||||
static int do_x509_check(X509 *x, const char *chk, size_t chklen,
|
||||
unsigned int flags, int check_type, char **peername)
|
||||
{
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
const X509_NAME *name = NULL;
|
||||
int i;
|
||||
int cnid = NID_undef;
|
||||
int alt_type;
|
||||
int san_present = 0;
|
||||
int rv = 0;
|
||||
equal_fn equal;
|
||||
|
||||
/* See below, this flag is internal-only */
|
||||
flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
|
||||
if (check_type == GEN_EMAIL) {
|
||||
cnid = NID_pkcs9_emailAddress;
|
||||
alt_type = V_ASN1_IA5STRING;
|
||||
equal = equal_email;
|
||||
} else if (check_type == GEN_DNS) {
|
||||
cnid = NID_commonName;
|
||||
/* Implicit client-side DNS sub-domain pattern */
|
||||
if (chklen > 1 && chk[0] == '.')
|
||||
flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
|
||||
alt_type = V_ASN1_IA5STRING;
|
||||
if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
|
||||
equal = equal_nocase;
|
||||
else
|
||||
equal = equal_wildcard;
|
||||
} else {
|
||||
alt_type = V_ASN1_OCTET_STRING;
|
||||
equal = equal_case;
|
||||
}
|
||||
|
||||
if (chklen == 0)
|
||||
chklen = strlen(chk);
|
||||
|
||||
gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
|
||||
if (gens) {
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
|
||||
GENERAL_NAME *gen;
|
||||
ASN1_STRING *cstr;
|
||||
|
||||
gen = sk_GENERAL_NAME_value(gens, i);
|
||||
if ((gen->type == GEN_OTHERNAME) && (check_type == GEN_EMAIL)) {
|
||||
if (OBJ_obj2nid(gen->d.otherName->type_id) ==
|
||||
NID_id_on_SmtpUTF8Mailbox) {
|
||||
san_present = 1;
|
||||
|
||||
/*
|
||||
* If it is not a UTF8String then that is unexpected and we
|
||||
* treat it as no match
|
||||
*/
|
||||
if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) {
|
||||
cstr = gen->d.otherName->value->value.utf8string;
|
||||
|
||||
/* Positive on success, negative on error! */
|
||||
if ((rv = do_check_string(cstr, 0, equal, flags,
|
||||
chk, chklen, peername)) != 0)
|
||||
break;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if ((gen->type != check_type) && (gen->type != GEN_OTHERNAME))
|
||||
continue;
|
||||
}
|
||||
san_present = 1;
|
||||
if (check_type == GEN_EMAIL)
|
||||
cstr = gen->d.rfc822Name;
|
||||
else if (check_type == GEN_DNS)
|
||||
cstr = gen->d.dNSName;
|
||||
else
|
||||
cstr = gen->d.iPAddress;
|
||||
/* Positive on success, negative on error! */
|
||||
if ((rv = do_check_string(cstr, alt_type, equal, flags,
|
||||
chk, chklen, peername)) != 0)
|
||||
break;
|
||||
}
|
||||
GENERAL_NAMES_free(gens);
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We're done if CN-ID is not pertinent */
|
||||
if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT))
|
||||
return 0;
|
||||
|
||||
i = -1;
|
||||
name = X509_get_subject_name(x);
|
||||
while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
|
||||
const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
|
||||
const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne);
|
||||
|
||||
/* Positive on success, negative on error! */
|
||||
if ((rv = do_check_string(str, -1, equal, flags,
|
||||
chk, chklen, peername)) != 0)
|
||||
return rv;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user