LIBRESSL-X509V3_ADDR_VALIDATE_PATH(3)

πŸ“¦ version 4.4.0, in alpine 3.24, arch rolling

πŸ’… X509v3_addr_validate_path β€” RFC 3779 path validation (libcrypto, section 3)

okay so this is the libcrypto manpage for four functions that do RFC 3779 path validation for IP address and AS number delegation, and honestly? it's giving "niche but important." stick with me bestie 🫢

✨ NAME ✨

X509v3_addr_validate_path, X509v3_addr_validate_resource_set, X509v3_asid_validate_path, X509v3_asid_validate_resource_set β€” RFC 3779 path validation for IP address and AS number delegation πŸ¦‹


🌸 SYNOPSIS 🌸

library β€œlibcrypto” #include <openssl/x509v3.h>

int
X509v3_addr_validate_path(X509_STORE_CTX *ctx);

int
X509v3_addr_validate_resource_set(STACK_OF(X509) *chain,
    IPAddrBlocks *addrblocks, int allow_inherit);

int
X509v3_asid_validate_path(X509_STORE_CTX *ctx);

int
X509v3_asid_validate_resource_set(STACK_OF(X509) *chain,
    ASIdentifiers *asid, int allow_inherit);

like yes that's a lot of signatures, but you're gonna slay them one at a time πŸ’–


πŸŽ€ DESCRIPTION πŸŽ€

So the thing is: both RFC 3779 extensions need extra checking in the certification path validation. like, they're not gonna validate themselves, bestie. here are the rules, and they're literally the whole plot of this page:

  1. The initial set of allowed IP address and AS number resources is defined in the trust anchor, where inheritance is not allowed. πŸ™…β€β™€οΈ
  2. An issuer may only delegate subsets of resources present in its RFC 3779 extensions, or subsets of resources inherited from its issuer.
  3. If an RFC 3779 extension is present in a certificate, the same type of extension must also be present in its issuer. the way that's non-negotiable 😀
  4. All RFC 3779 extensions appearing in the validation path must be in canonical form according to X509v3_addr_is_canonical(3) and X509v3_asid_is_canonical(3). canonical or bye ✨

πŸ’œ the path validation girlies

X509v3_addr_validate_path() and X509v3_asid_validate_path() are called from X509_verify_cert(3) as part of the verification chain building. that's their whole job. 🫑

When they hit an error or a violation of the rules above, they set error, error_depth, and current_cert on ctx, and the verify callback gets called with ok set to 0. the drama of it all πŸ’€

The error codes, bestie, pay attention:

  • X509_V_ERR_INVALID_EXTENSION means a non-canonical resource πŸ™ˆ
  • X509_V_ERR_UNNESTED_RESOURCE means a violation of the other rules above
  • In rare circumstances, the error can be X509_V_ERR_UNSPECIFIED β€” and for IP address resources, X509_V_ERR_OUT_OF_MEM is also possible 😭

πŸ¦‹ the resource_set girlies

X509v3_addr_validate_resource_set() validates the resources in addrblocks against a specific certificate chain. here's the routine, no cap:

  • first it checks that addrblocks is canonical
  • then its IP addresses get checked to be covered in the certificate at depth 0
  • then it walks the chain all the way to the trust anchor until it hits an error or a violation of the rules above

and addrblocks is allowed to use inheritance according to X509v3_addr_inherits(3) if and only if allow_inherit is non-zero.

X509v3_asid_validate_resource_set() performs similar checks as X509v3_addr_validate_resource_set() for asid. same vibe, AS numbers instead ✨


🧚 RETURN VALUES 🧚

All these functions return 1 on successful validation and 0 otherwise. iconic binary behaviour, we love to see it πŸ‘‘

⭐ X509v3_addr_validate_path() and X509v3_asid_validate_path()

A non-empty chain and a verify_cb must be present on ctx, otherwise they fail and set the error on ctx to X509_V_ERR_UNSPECIFIED. rude but valid.

The verify_cb is called with the error codes described above on most errors encountered during validation. but β€” some malformed extensions can lead to an error that cannot be intercepted by the callback. yeah, those ones are sneaky 😬

With the exception of an allocation error, no error codes are set on the error stack.

🌈 X509v3_addr_validate_resource_set() and X509v3_asid_validate_resource_set()

  • X509v3_addr_validate_resource_set() accepts a NULL addrblocks and X509v3_asid_validate_resource_set() accepts a NULL asid as valid 🀝
  • They fail if chain is NULL or empty 🚫
  • If allow_inherit is 0, addrblocks or asid is checked for inheritance with X509v3_addr_inherits(3) or X509v3_asid_inherits(3)
  • The remaining failure cases are the same as for X509v3_addr_validate_path() and X509v3_asid_validate_path()
heads up bestie: they cannot and do not attempt to communicate the cause of the error to the caller. so like, you get a 0 and that's the whole message. no notes, no explanation, just vibes πŸ’€

πŸ”₯ SEE ALSO πŸ”₯

ASIdentifiers_new(3), crypto(3), IPAddressRange_new(3), X509_new(3), X509_STORE_CTX_get_error(3), X509_verify_cert(3), X509v3_addr_add_inherit(3), X509v3_addr_inherits(3), X509v3_asid_add_id_or_range(3)

go read those too, they're the supporting cast and they ate πŸ’…


🌸 STANDARDS 🌸

RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers:

  • section 2.3: IP Address Delegation Extension Certification Path Validation
  • section 3.3: Autonomous System Identifier Delegation Extension Certification Path Validation

RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

  • section 6: Certification Path Validation

the citations? immaculate. periodt πŸ“š


πŸ’– HISTORY πŸ’–

These functions first appeared in OpenSSL 0.9.8e and have been available since OpenBSD 7.1. they've been doing this longer than you've been alive, lowkey πŸ‘‘


okay that's the whole page, bestie, you're officially certified in RFC 3779 path validation πŸŽ“βœ¨ this little number came out of the Debian build dated June 8, 2025 β€” mwah, thanks Debian, you ate πŸ«ΆπŸ’œ

πŸ“¦ where this page comes from