nx_x509_san.nx
buildroot/runtime/nx_x509_san.nx
about
nx_x509_san.nx -- X.509 Subject Alternative Name walk + hostname
match (RFC 5280 §4.2.1.6 + RFC 6125 §6.4).
Phase 0b §I.2.C of the Nishi TLS 1.3 stack. Composes the
X509Cert.extensions_off/_len captured by nx_x509.x509_parse
(commit c45b19e7) into the SAN-dNSName hostname-match check
that any real Web PKI cert chain must pass.
ASN.1 structure (RFC 5280 §4.2.1.6):
Extensions ::= SEQUENCE OF Extension (outer at extensions_off)
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER, -- 2.5.29.17 for SAN
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING -- DER-encoded SAN
}
SubjectAltName ::= GeneralNames (lives inside extnValue)
GeneralNames ::= SEQUENCE OF GeneralName
GeneralName ::= CHOICE { -- [2] tag is dNSName
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER
}
SAN OID 2.5.29.17 encoded as DER: 06 03 55 1D 11 (tag 0x06, len 3,
content 0x55 0x1D 0x11).
dNSName context-tag byte: [2] IMPLICIT IA5String = 0x82.
Hostname matching rules (RFC 6125 §6.4):
1. Exact case-insensitive match of whole hostname -> MATCH.
2. Wildcard "*" allowed ONLY as left-most label:
pattern = "*.example.com"
dependencies 3 imports · 4 importers
imports: nx_syscalls.nxnx_asn1.nxnx_x509.nx
imported by: nx_edge_probe.nxnx_x509_leaf_check.nxnx_x509_leaf_check_test.nxnx_x509_san_test.nx
structs
| none |
consts
| 79 | const NX_X509_SAN_OK: i64 = 1 // host matched a SAN dNSName entry |
| 80 | const NX_X509_SAN_NO_MATCH: i64 = 2 // SAN present, no dNSName matched |
| 81 | const NX_X509_SAN_NO_EXTENSIONS: i64 = 3 // cert has no v3 extensions block |
| 82 | const NX_X509_SAN_NO_SAN: i64 = 4 // extensions present, no SAN OID |
| 83 | const NX_X509_SAN_BAD_FORMAT: i64 = 5 // malformed extension data |
| 84 | const NX_X509_SAN_BAD_PATTERN: i64 = 6 // SAN entry has illegal wildcard placement |
| 85 | const NX_X509_SAN_VERDICT_N: i64 = 7 |
functions
| 87 | func nx_x509_san_verdict_is_valid(v: i64) -> i64 called by 1: main |
| 95 | func ascii_to_lower(b: i64) -> i64 called by 1: bytes_eq_ci |
| 106 | func bytes_eq_ci(a: *u8, alen: i64, b: *u8, blen: i64) -> i64 |
| 119 | func count_byte(buf: *u8, len: i64, needle: i64) -> i64 called by 1: hostname_wildcard_match |
| 149 | func hostname_wildcard_match(pattern: *u8, plen: i64, |
| 203 | func x509_san_locate(buf: *u8, cert: *X509Cert, |
| 306 | func x509_san_match_hostname(buf: *u8, cert: *X509Cert, |
| 348 | func main() -> i64 |