diff options
author | Michael Brown | 2012-03-21 20:18:38 +0100 |
---|---|---|
committer | Michael Brown | 2012-03-21 20:19:28 +0100 |
commit | b1316ef27670d3dba06c61487fbe91222b5d050b (patch) | |
tree | 653804732e78346a15f2dd922da8e1a02a8a7ce0 /src/crypto/x509.c | |
parent | [crypto] Treat ASN.1 OIDs as opaque (diff) | |
download | ipxe-b1316ef27670d3dba06c61487fbe91222b5d050b.tar.gz ipxe-b1316ef27670d3dba06c61487fbe91222b5d050b.tar.xz ipxe-b1316ef27670d3dba06c61487fbe91222b5d050b.zip |
[crypto] Validate path length constraint in certificate chain
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto/x509.c')
-rw-r--r-- | src/crypto/x509.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/crypto/x509.c b/src/crypto/x509.c index a11eee6f..449d07e2 100644 --- a/src/crypto/x509.c +++ b/src/crypto/x509.c @@ -89,6 +89,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); __einfo_error ( EINFO_EACCES_EXPIRED ) #define EINFO_EACCES_EXPIRED \ __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" ) +#define EACCES_PATH_LEN \ + __einfo_error ( EINFO_EACCES_PATH_LEN ) +#define EINFO_EACCES_PATH_LEN \ + __einfo_uniqify ( EINFO_EACCES, 0x05, "Maximum path length exceeded" ) /** "commonName" object identifier */ static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME }; @@ -1187,6 +1191,7 @@ int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert, struct x509_certificate *current = &temp[0]; struct x509_certificate *next = &temp[1]; struct x509_certificate *swap; + unsigned int path_len = 0; int rc; /* Use default root certificate store if none specified */ @@ -1226,6 +1231,15 @@ int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert, if ( ( rc = x509_validate_issuer ( current, next ) ) != 0 ) return rc; + /* Validate path length constraint */ + if ( path_len > next->extensions.basic.path_len ) { + DBGC ( context, "X509 chain %p path length %d exceeds " + "maximum %d\n", context, path_len, + next->extensions.basic.path_len ); + return -EACCES_PATH_LEN; + } + path_len++; + /* Move to next certificate in chain */ swap = current; current = next; |