summaryrefslogtreecommitdiffstats
path: root/src/crypto/x509.c
diff options
context:
space:
mode:
authorMichael Brown2012-03-21 20:18:38 +0100
committerMichael Brown2012-03-21 20:19:28 +0100
commitb1316ef27670d3dba06c61487fbe91222b5d050b (patch)
tree653804732e78346a15f2dd922da8e1a02a8a7ce0 /src/crypto/x509.c
parent[crypto] Treat ASN.1 OIDs as opaque (diff)
downloadipxe-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.c14
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;