aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/x509/x509cert.cpp2
-rw-r--r--src/lib/x509/x509path.cpp37
-rw-r--r--src/tests/data/extended_x509/01/end.crt19
-rw-r--r--src/tests/data/extended_x509/01/int.crt18
-rw-r--r--src/tests/data/extended_x509/01/root.crt18
-rw-r--r--src/tests/data/extended_x509/02/end.crt20
-rw-r--r--src/tests/data/extended_x509/02/int1-2.crt20
-rw-r--r--src/tests/data/extended_x509/02/int1.crt20
-rw-r--r--src/tests/data/extended_x509/02/root.crt20
-rw-r--r--src/tests/data/extended_x509/03/end.crt20
-rw-r--r--src/tests/data/extended_x509/03/int1.crt20
-rw-r--r--src/tests/data/extended_x509/03/root.crt20
-rw-r--r--src/tests/data/extended_x509/expected.txt3
-rw-r--r--src/tests/test_x509_path.cpp78
14 files changed, 310 insertions, 5 deletions
diff --git a/src/lib/x509/x509cert.cpp b/src/lib/x509/x509cert.cpp
index 512e4aa63..40bdbf477 100644
--- a/src/lib/x509/x509cert.cpp
+++ b/src/lib/x509/x509cert.cpp
@@ -334,7 +334,7 @@ bool X509_Certificate::has_ex_constraint(const std::string& ex_constraint) const
*/
uint32_t X509_Certificate::path_limit() const
{
- return m_subject.get1_uint32("X509v3.BasicConstraints.path_constraint", 0);
+ return m_subject.get1_uint32("X509v3.BasicConstraints.path_constraint", Cert_Extension::NO_CERT_PATH_LIMIT);
}
/*
diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp
index 8521e51a7..a06df2460 100644
--- a/src/lib/x509/x509path.cpp
+++ b/src/lib/x509/x509path.cpp
@@ -76,13 +76,9 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce
status.insert(Certificate_Status_Code::CERT_HAS_EXPIRED);
// Check issuer constraints
-
if(!issuer->is_CA_cert() && !self_signed_ee_cert)
status.insert(Certificate_Status_Code::CA_CERT_NOT_FOR_CERT_ISSUER);
- if(issuer->path_limit() < i)
- status.insert(Certificate_Status_Code::CERT_CHAIN_TOO_LONG);
-
std::unique_ptr<Public_Key> issuer_key(issuer->subject_public_key());
if(!issuer_key)
@@ -115,6 +111,39 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce
}
}
+ // path len check
+ size_t max_path_length = cert_path.size();
+ for(size_t i = cert_path.size() - 1; i > 0 ; --i)
+ {
+ std::set<Certificate_Status_Code>& status = cert_status.at(i);
+ const std::shared_ptr<const X509_Certificate>& subject = cert_path[i];
+
+ /*
+ * If the certificate was not self-issued, verify that max_path_length is
+ * greater than zero and decrement max_path_length by 1.
+ */
+ if(subject->subject_dn() != subject->issuer_dn())
+ {
+ if(max_path_length > 0)
+ {
+ --max_path_length;
+ }
+ else
+ {
+ status.insert(Certificate_Status_Code::CERT_CHAIN_TOO_LONG);
+ }
+ }
+
+ /*
+ * If pathLenConstraint is present in the certificate and is less than max_path_length,
+ * set max_path_length to the value of pathLenConstraint.
+ */
+ if(subject->path_limit() != Cert_Extension::NO_CERT_PATH_LIMIT && subject->path_limit() < max_path_length)
+ {
+ max_path_length = subject->path_limit();
+ }
+ }
+
return cert_status;
}
diff --git a/src/tests/data/extended_x509/01/end.crt b/src/tests/data/extended_x509/01/end.crt
new file mode 100644
index 000000000..5d05a8e5e
--- /dev/null
+++ b/src/tests/data/extended_x509/01/end.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAbMQswCQYDVQQGEwJERTEM
+MAoGA1UEAxMDSW50MB4XDTE3MDMzMTIwMzYwMFoXDTE4MDMzMTIwMzYwMFowGjEL
+MAkGA1UEBhMCREUxCzAJBgNVBAMTAkVFMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAt3ZPYYEIMIAViK68jKugGUMIISV4X7JjUz3/k44E2E2ovPem7mhq
+JPOzKpaS9+AOzEIJQIT+a6Re4+DmUNvW9Zm6P2J4Lrc8ixoCejMSwrtyqCCTJ+ef
+i6o82d0Tgge4ZnudiIzozUJy1rAS5T+rV6re3SUdKdjgLkva735Bve67/gS9eh5L
+AIQpN8ZPa4+qzbwfGZe3PGgOV2701LzQCrVRe7KWpm1ZjOi5WTRh0xAHiC6WpM2F
+eF0aRkC18Sat3FTi0ba2cqikttPnghFhShLUyUvn/LrLsk/ajGaArbV88Hk+p8l/
+pXhNh1X0zftxS/Fa1QCFbb4OxQMSmGZgMwIDAQABo1wwWjAMBgNVHRMBAf8EAjAA
+MB0GA1UdDgQWBBRH3e2M6wVjMMj76gDRe1/q5KkFwDALBgNVHQ8EBAMCBLAwHgYJ
+YIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEA
+TF2AdhF57cBnjmeiv+HKKgjybWvA2X14k+rdRasNg87oJ/v2Kf/llJkUu2vs44tQ
+8HrmET6nq+0dPdJL4SsgyYqCW82hGh0W1saSFyCq+Wbk4DSFbHopOxlbbgX4GUJ/
+wfRY6BVRhz3IdPR4TM0zJ4o3nk+OTfBi+3ckfaK5DYNsnYbZwoG92ISMSRHGmg6g
+UYXOVmHmzIFK0ESl8+om2VsbWPRUCBOtU1BJLYwpx4RyIBBYPHR4npu+OpNrcBzR
+MaZuHuoKbqvZlvCclbd37YffyWryOGEf+YcjQPy8BqFMUQBBRH9gW4Ph819UYFpb
+IozFU/jYzXzXoxG4hMqtHA==
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/01/int.crt b/src/tests/data/extended_x509/01/int.crt
new file mode 100644
index 000000000..b6708f169
--- /dev/null
+++ b/src/tests/data/extended_x509/01/int.crt
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC8TCCAdmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAcMQswCQYDVQQGEwJERTEN
+MAsGA1UEAxMEUm9vdDAeFw0xNzAzMzEyMDM1MDBaFw0yNzAzMzEyMDM1MDBaMBsx
+CzAJBgNVBAYTAkRFMQwwCgYDVQQDEwNJbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQC7vyhLG+LWNHi/7MdX971HRqc8TD0aSG4nbclEeV+mGPRhdbVD
+A+ZQn8Bj26iqRMJ8WT6+/M1rycOaAcEsfGSjPCSqrBuyo973nqMgiTfCgucFYtj/
+jkUArJQ8yuNJkLXkQK+4S0iSA1h7nPLwC967qPKcJnQgeHJDjKU9AefXoda66zxO
+kbaX4y5oY346tWP/0pjDeo2zix15jajPrAvCtDFJrYni71ixFNHZRI159cscSvfR
+I2lNnkUJ/M/6UnwflYgin7N/DHk/oad96bXatuKmdCWA/5R4FAnAhwdL7sbTy4LL
+jV8amewEhSn51iSFqVIm6wO7NiZw8D3/603TAgMBAAGjPzA9MA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFHs9prehJUV7V9rn0KlYPmZqzRXXMAsGA1UdDwQEAwIB
+BjANBgkqhkiG9w0BAQsFAAOCAQEADsKaZEuxy9upg0HTxWy2RfY8im+Xg5qkU2IW
++vSFr1QoZWVn59y3WzeoBqi9dFquQyUjTvPUHJoplh9CvHWZbL0ih/NUt70uy/Jz
+kyacpcFEbiAZD6sPCe6JwOSrEAEnTRDpP2Gn6gRxVOXGptMFpX54yxf4shZJnyy/
+r1iY11WQGy4qJS+20eUj4CxqletBzKfMiar9oX9sJl/Go1KzZexnIqli2v1/KevX
+6PRc+ubmz4aZzkRzP9v0Ie8YxJmjY5LLnhjY/G2GV8I6p8y5UqYkYRPvGJXB5WAi
+1b6uvuEhgatAelk1mn95Pv7W8ASLWbbV4OippdZUdOCkxs/D+w==
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/01/root.crt b/src/tests/data/extended_x509/01/root.crt
new file mode 100644
index 000000000..f83c6c516
--- /dev/null
+++ b/src/tests/data/extended_x509/01/root.crt
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC9TCCAd2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMQswCQYDVQQGEwJERTEN
+MAsGA1UEAxMEUm9vdDAeFw0xNzAzMzEyMDMzMDBaFw0yNzAzMzEyMDMzMDBaMBwx
+CzAJBgNVBAYTAkRFMQ0wCwYDVQQDEwRSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA86tiSCsS6wRGe/iylnLS3WnxcWM/x8qrQZQ5JAaB7LMR6Dfp
+DSBk9vU4/h0CbYVr9+7an3dEDA6Raoh+qLDklspqDQ5cXlYee8GMutQbSTxtKA+4
+fgIrT18JyBu993IBszwj01BVD+Ibun+Bw/pg7dYD3w+T60njMb4EirU5/0e1CKxB
+iv5UEY7R6DkIU4QXHzvj0Dstls5XTsIAODuh4IEwsnMq9ZQi7Cl4AflUABAY0w6B
+nEhbb3wMmg1ndDnv9RcOP3IQzIFuQG3i8SdH1Rik/00N9Mom7sRCulrPhZoNFbTV
+tQ9PZ8iQPUNzJNrIkWZ/O9uN023wtbiGlgSytQIDAQABo0IwQDASBgNVHRMBAf8E
+CDAGAQH/AgEBMB0GA1UdDgQWBBRfG0Pzn9XuCESFgLCJOWpwAC/XFDALBgNVHQ8E
+BAMCAQYwDQYJKoZIhvcNAQELBQADggEBAH2RqhCbx3SjljbbqPq8dxUccLvtIf/S
+oxPn7ogdG3WuwfCQzXJ7v0HwcLTytF+/zYYgPTip9RmQdVqym9YjlDAG5NlFQm3b
+jYZQ0gUrG56tb57K1YjQcrUU15ewbILZU0N0gfs+p1PMUkFsVVsPienO7j0aRKmB
+U6Ecgma8kS/++QvlFlgXE+shdzXjN92nuqHeJ8aNaPb7ueD6b82+LK8ZuCPPtHUN
+EdCzKWYlHzMKklLVbfzXbHG5yiiim9OaFqsY+7ljWJiT//s5bbGRJjBb2GCSwVvI
+wOubEvVrJ02l7U69LxaHsXXRlKw3vq1Z3HbKAIJlWMIPvaFQKnY9RdI=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/02/end.crt b/src/tests/data/extended_x509/02/end.crt
new file mode 100644
index 000000000..b0dc343b6
--- /dev/null
+++ b/src/tests/data/extended_x509/02/end.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDOzCCAiOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgSW50MSBDQTAeFw0xNzA1MTcxMjQyMDBaFw0xODA1MTcxMjQyMDBa
+MBoxGDAWBgNVBAMTD1BhdGhMZW4gVGVzdCBFRTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMrhTUs/sAT4S2JMYFh8Z7bSzgQLqt3l+cAW1mgiw3ydh0+L
+aytLRmyJrX0K6B2zEZKilbPXPJW2O1fY5lIvrYz0HGJRcQWRhZ9IaAqkWNSrIGR6
+bCodpDH/Lr3nUuvsaLobFs+e+YLdXu1TwQMBieIi5eXuwaPIpcGi8Byl2iBsS9UT
+CYDj08rwOwF8f/zgWJK/2to2TraHTHw+rjlOL5MEXxjLC50ZnKaAzw4K49mnRv8U
+exzs67250Sa0ZONB3nh1/Z+FBNIsdXcNDoMtn04/sk1F/TF3f8jA3h+HOvfGrE6O
+dqJ6DJK4UD/RqfRiD0+6Spcx+eu2rR2ss9ISKJ8CAwEAAaOBhjCBgzAMBgNVHRMB
+Af8EAjAAMB0GA1UdDgQWBBTrUJdF9MaI2YaBus2Teo09rq/YEDBHBgNVHSMEQDA+
+gBRBtmp9tx8Q7LqmvCh8n9jxgmLcsqEjpCEwHzEdMBsGA1UEAxMUUGF0aExlbiBU
+ZXN0IEludDEgQ0GCAQMwCwYDVR0PBAQDAgXgMA0GCSqGSIb3DQEBCwUAA4IBAQBA
+q9bK4nMz0H2vLmSfiqbNB7chjKztAzQkD1YZTDmyuDVFXNu6ooClWOIOAPj0/XrL
+s2LHz0KodS4QkEStoK8lsFDmo6lNCKVkGsSNUUwmWa2P43EpmzZdVSd0tk/BSA0O
+dPifwTncW9hsseHoe5G29ddLdnRE9MH/5rrLOMFPSa0wHOXNqbt6wAANTwrBY+QV
+xFQSmkBiICqJqCpcqe7gH/x9lgNYdQxBCnR6pitj6uxmOLl40qzfVfzKQe8hovyA
+piOjaYJ4i4j7xl3nlsw4CjaRitpDwLXjL8LQfdoOD/FWj18+DFcH59azqBjoyr6x
+OtnVSv2VDcvcvhNHiqCy
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/02/int1-2.crt b/src/tests/data/extended_x509/02/int1-2.crt
new file mode 100644
index 000000000..6c93d0492
--- /dev/null
+++ b/src/tests/data/extended_x509/02/int1-2.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRjCCAi6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgSW50MSBDQTAeFw0xNzA1MTcxMjQxMDBaFw0yNzA1MTcxMjQxMDBa
+MB8xHTAbBgNVBAMTFFBhdGhMZW4gVGVzdCBJbnQxIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAoQGuLP6gafHVnoyFbtTVBV+Svc6TwG6nBLWMj5oI
+csWF5815WuDKJCIef0FzT81ew2PqxJKqvwu68+IW6v5EmIMO99fig80/o/IVWwuv
+/ycRIth4UJsEpg25QUiFwBcmeJ3Hhjrf+2cPqKLT7dCiz+FJY6fXQdpo8vtJVMSa
+8u5oA0NoSYnVnRrT8mDP2io1egWkwdFjn4JLZ99UYVBCEi/Pp3DNhtkn3rwaIm6v
+SGxKxtgHWqTmldeCB+k7YVOPOYLbAlhNknpXFiU4Op0hEFMtgnUXGH5s2bJNM0sS
+VOBG78UIfRPxumkPYelzPCUsYbRJ7PulybtNdtWFPtlDewIDAQABo4GMMIGJMBIG
+A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEG2an23HxDsuqa8KHyf2PGCYtyy
+MEcGA1UdIwRAMD6AFNtU+/YoX0TQdnd50WtkXsyilRoGoSOkITAfMR0wGwYDVQQD
+ExRQYXRoTGVuIFRlc3QgUm9vdCBDQYIBAjALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN
+AQELBQADggEBAKWTS0/h4bDNbBQaELSMbYyyNw+WQKRJKRawoC9d89JywD/1xjM2
+byCySAOdsuWX5t8PuDIHjLu4vykF792Cpx3ToWztHTPYkpg/Ci25H4Vvhbdlb62X
+h712cQ0hEdrNC5Uahl3jUpYfdktF8un3fp33yazlF2PHswWtgFBpU3u0GZi4R7ft
+CsY1XzzxaEjBwfu8vDLf/kkdJBpXh97rkGhfogNSJ4+EAlqbJ+rTj1ucW7ou9M9d
+vvIHAx1lJWERoSDUDOIigpJaHSs2kIvF1/+pCW7pJiZ2EwD5S0Kj0m+6Evic/Vo0
+6Ff9EE6WPEMY4p3ykFc6+TIOj8Xbw03VFWI=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/02/int1.crt b/src/tests/data/extended_x509/02/int1.crt
new file mode 100644
index 000000000..66a5d9a8c
--- /dev/null
+++ b/src/tests/data/extended_x509/02/int1.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRjCCAi6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgUm9vdCBDQTAeFw0xNzA1MTcxMjQxMDBaFw0yNzA1MTcxMjQxMDBa
+MB8xHTAbBgNVBAMTFFBhdGhMZW4gVGVzdCBJbnQxIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAvcX2nM3+B9OTzmVbl80c6rBnoCCINvrsRNEqPET5
+zF5NSGZzJJo3GF9iZCov4rLSWIgyHqekWIbs5JximdIc5JaNkEeic6RYU4u+5GFI
+ki2qXfNiqIPgxAO2F8/7W0nXa5B+2kH8d62m2um8ONY6f1NkBM+bTLgMb78K3js4
+eftYjRVd3EFzBEiIVKj3VyGRtbiNWZCRbT7/X4tCjYVwjFZejbyZkQJv5qhbWv0X
+Il/6gNbvN5P1Iumy5yBfKwonJiYyLv3DZME5sexzAJa7OxNEwJApuY+93soA0iLd
+1WyzNpeL4hzNvpYUi5YuiLjA5oHLPmFYN96wKUAP9yWhfwIDAQABo4GMMIGJMBIG
+A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFNtU+/YoX0TQdnd50WtkXsyilRoG
+MEcGA1UdIwRAMD6AFOphOYxY6kM+m0UT5FTvNLzki+2HoSOkITAfMR0wGwYDVQQD
+ExRQYXRoTGVuIFRlc3QgUm9vdCBDQYIBATALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN
+AQELBQADggEBAHyi1KRBgrpu/bxiioRchfZN9AtVS2qeohA0WkDZbdbgI5j/sqgy
+IfVVQizBJVeTfFuv6C2davHnnpoDUTYwY4tiQz4ZJtTm2zLmUw3ennujlLJeBP5O
+ykjcU7lxAmf6vAdMvqRuIHvx/nYgE2G3T6sx7Doa5kdruCHosLvuUU6sP0cQjxsH
+x0gbDTvE+DjIjrSlCAVBwNB0zcOHG0A/fV2SEHy4Pi/JthEvXExngXnNMFlPEA58
+1FL8M0bpxW3M2tchFoGhTrSDt4hkYqsV1kGK8zXgqT9PxyaSE9lvNjBVtGNbt+9Q
+jMbhRokpXaUALVxpHN5gC2YOO9yYD40EPUU=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/02/root.crt b/src/tests/data/extended_x509/02/root.crt
new file mode 100644
index 000000000..c66ac1c00
--- /dev/null
+++ b/src/tests/data/extended_x509/02/root.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRjCCAi6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgUm9vdCBDQTAeFw0xNzA1MTcxMjM5MDBaFw0yNzA1MTcxMjM5MDBa
+MB8xHTAbBgNVBAMTFFBhdGhMZW4gVGVzdCBSb290IENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAwGl+aRGnJVyfSZlnoD+r9R8KjsJE6aduNtmDrTxE
+XkKceCfcqDyCVyF7jufmxrLnSEHEz4cx3hMGkG3SrsWmpzoIrSbvLliJs8uopBHv
+yojTRoCMHP6BQeRIFl/Z9g0NMpP+wC2a2pLL6Notsc2WCMbZOelx8JpyZDgHMmgg
+JiHydtTf5jw6U8O/KRoAJcd8cNMnWHb+ibwZ621WpFk38C9RA95lNhF3GoAKRAxb
+4VV0b1UXDfWEo2ame7PHJv2COv4ufWfMVn011nrUYU8AuzJX+mZj3dFqbvri9rB1
+KVzYkZkhf+ih3BMbH/ZZn18LU3IDwkLubYpE9Vnd75DxsQIDAQABo4GMMIGJMBIG
+A1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFOphOYxY6kM+m0UT5FTvNLzki+2H
+MEcGA1UdIwRAMD6AFOphOYxY6kM+m0UT5FTvNLzki+2HoSOkITAfMR0wGwYDVQQD
+ExRQYXRoTGVuIFRlc3QgUm9vdCBDQYIBATALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN
+AQELBQADggEBAHAIh/0/urh5Z5uY0D5XtGQ5ZVHSGb23i15mVFDQafMy1G5wsKRx
+/cO/Gg7U0TuAl8mxvOlJtLCIC/1RybRegmhkzsxWZVaavxlZvRW+mpquJBA32+Qn
+Tc8tdYftICzgowdCl0m2RlZJXDOc6//8LUqcIsz85XOeBjMMRSrkGIJU/Iq4xSyd
+zIqH+iilsP5r9MzBWCtwWFzy/noZAtl9aaHFtCPVTAE6L4rXxPEKFJ65nQdSl2pN
+4KqR6JImoGLoat87sVDjs4GJdbcyx6GSo8Qgj7cbxGkkD87jfPeqFMCJlf0bkTxX
+xgbGs+HNsuzjl5bfZtCFLDYVGrJ+TlFTn/s=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/03/end.crt b/src/tests/data/extended_x509/03/end.crt
new file mode 100644
index 000000000..d4ef54dcf
--- /dev/null
+++ b/src/tests/data/extended_x509/03/end.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDQzCCAiugAwIBAgIBBDANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgSW50MSBDQTAeFw0xNzA1MTcxMjQ2MDBaFw0yNzA1MTcxMjQ2MDBa
+MB8xHTAbBgNVBAMTFFBhdGhMZW4gVGVzdCBJbnQyIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAoQGuLP6gafHVnoyFbtTVBV+Svc6TwG6nBLWMj5oI
+csWF5815WuDKJCIef0FzT81ew2PqxJKqvwu68+IW6v5EmIMO99fig80/o/IVWwuv
+/ycRIth4UJsEpg25QUiFwBcmeJ3Hhjrf+2cPqKLT7dCiz+FJY6fXQdpo8vtJVMSa
+8u5oA0NoSYnVnRrT8mDP2io1egWkwdFjn4JLZ99UYVBCEi/Pp3DNhtkn3rwaIm6v
+SGxKxtgHWqTmldeCB+k7YVOPOYLbAlhNknpXFiU4Op0hEFMtgnUXGH5s2bJNM0sS
+VOBG78UIfRPxumkPYelzPCUsYbRJ7PulybtNdtWFPtlDewIDAQABo4GJMIGGMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEG2an23HxDsuqa8KHyf2PGCYtyyMEcG
+A1UdIwRAMD6AFNtU+/YoX0TQdnd50WtkXsyilRoGoSOkITAfMR0wGwYDVQQDExRQ
+YXRoTGVuIFRlc3QgUm9vdCBDQYIBAzALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEL
+BQADggEBAJMJUlCtT9OCt6G/jNRcZrsxprlVvGBpLItHF6Kol+gs/Pz93c3rLxj6
+czp2OqjZFsm6k0Fl6kSrBQHRH/dZdKZlsNtMnrF0RXonuJVBaSONKC6SFOc4E9qa
+nNfx/AB40IGdhKbgHNS/92Q4kIwV2JfbQPXTmOvFTtFH/saUoTmlMWaBIeEEjQX2
+/NjyCvSUvKVwAgTF/HWspzjuEVukiCszVOQV8UuhEnLSdvztuguf0CkM93W17x7t
+//R04hz+TOLCAp5OzeZB4y4UE+oroo1ynzdTnQ7PHMxh67+mX2piawc00zyHqqTf
+09z9uN4HmyJNQ4FXUvhC0Q+tISCaB68=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/03/int1.crt b/src/tests/data/extended_x509/03/int1.crt
new file mode 100644
index 000000000..1e4ec713e
--- /dev/null
+++ b/src/tests/data/extended_x509/03/int1.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDQzCCAiugAwIBAgIBAzANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgUm9vdCBDQTAeFw0xNzA1MTcxMjQ1MDBaFw0yNzA1MTcxMjQ1MDBa
+MB8xHTAbBgNVBAMTFFBhdGhMZW4gVGVzdCBJbnQxIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAvcX2nM3+B9OTzmVbl80c6rBnoCCINvrsRNEqPET5
+zF5NSGZzJJo3GF9iZCov4rLSWIgyHqekWIbs5JximdIc5JaNkEeic6RYU4u+5GFI
+ki2qXfNiqIPgxAO2F8/7W0nXa5B+2kH8d62m2um8ONY6f1NkBM+bTLgMb78K3js4
+eftYjRVd3EFzBEiIVKj3VyGRtbiNWZCRbT7/X4tCjYVwjFZejbyZkQJv5qhbWv0X
+Il/6gNbvN5P1Iumy5yBfKwonJiYyLv3DZME5sexzAJa7OxNEwJApuY+93soA0iLd
+1WyzNpeL4hzNvpYUi5YuiLjA5oHLPmFYN96wKUAP9yWhfwIDAQABo4GJMIGGMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNtU+/YoX0TQdnd50WtkXsyilRoGMEcG
+A1UdIwRAMD6AFOphOYxY6kM+m0UT5FTvNLzki+2HoSOkITAfMR0wGwYDVQQDExRQ
+YXRoTGVuIFRlc3QgUm9vdCBDQYIBATALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEL
+BQADggEBAK+euvQn4INuV1Dy12Vf8MYQQgFptU+ysBI8pXHxVjrR3VSk+LlNNwQ3
+50bKF/fNOb9YjosBYnPf/oL1O6yUEN+lNfsDwDK7P42poiUy4x+1oRua9AVYFKdP
+LTDhyfK/LQNMG3UizZLU7UwHZDTGpzeozUQB8yRIIJpnBw3hkD3ZK1GUGHiGPCN7
+A3f/D6sCRU3K9JIGrPjx8Nfuh9OEMsVDMCE2rGyhNz24EajFZoX+4C6lxzwDHMqR
+l7dW7TeplPalUHlpp1o+rJiJVxXTuL1cJr6jqmM1Uzbm/d/b2kwDyyX5xmTQBJ2g
+MqKPmIPvcEEsfuzOZCDb2HhSiaUI39M=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/03/root.crt b/src/tests/data/extended_x509/03/root.crt
new file mode 100644
index 000000000..c66ac1c00
--- /dev/null
+++ b/src/tests/data/extended_x509/03/root.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRjCCAi6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRQYXRo
+TGVuIFRlc3QgUm9vdCBDQTAeFw0xNzA1MTcxMjM5MDBaFw0yNzA1MTcxMjM5MDBa
+MB8xHTAbBgNVBAMTFFBhdGhMZW4gVGVzdCBSb290IENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAwGl+aRGnJVyfSZlnoD+r9R8KjsJE6aduNtmDrTxE
+XkKceCfcqDyCVyF7jufmxrLnSEHEz4cx3hMGkG3SrsWmpzoIrSbvLliJs8uopBHv
+yojTRoCMHP6BQeRIFl/Z9g0NMpP+wC2a2pLL6Notsc2WCMbZOelx8JpyZDgHMmgg
+JiHydtTf5jw6U8O/KRoAJcd8cNMnWHb+ibwZ621WpFk38C9RA95lNhF3GoAKRAxb
+4VV0b1UXDfWEo2ame7PHJv2COv4ufWfMVn011nrUYU8AuzJX+mZj3dFqbvri9rB1
+KVzYkZkhf+ih3BMbH/ZZn18LU3IDwkLubYpE9Vnd75DxsQIDAQABo4GMMIGJMBIG
+A1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFOphOYxY6kM+m0UT5FTvNLzki+2H
+MEcGA1UdIwRAMD6AFOphOYxY6kM+m0UT5FTvNLzki+2HoSOkITAfMR0wGwYDVQQD
+ExRQYXRoTGVuIFRlc3QgUm9vdCBDQYIBATALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN
+AQELBQADggEBAHAIh/0/urh5Z5uY0D5XtGQ5ZVHSGb23i15mVFDQafMy1G5wsKRx
+/cO/Gg7U0TuAl8mxvOlJtLCIC/1RybRegmhkzsxWZVaavxlZvRW+mpquJBA32+Qn
+Tc8tdYftICzgowdCl0m2RlZJXDOc6//8LUqcIsz85XOeBjMMRSrkGIJU/Iq4xSyd
+zIqH+iilsP5r9MzBWCtwWFzy/noZAtl9aaHFtCPVTAE6L4rXxPEKFJ65nQdSl2pN
+4KqR6JImoGLoat87sVDjs4GJdbcyx6GSo8Qgj7cbxGkkD87jfPeqFMCJlf0bkTxX
+xgbGs+HNsuzjl5bfZtCFLDYVGrJ+TlFTn/s=
+-----END CERTIFICATE-----
diff --git a/src/tests/data/extended_x509/expected.txt b/src/tests/data/extended_x509/expected.txt
new file mode 100644
index 000000000..ee6fc5943
--- /dev/null
+++ b/src/tests/data/extended_x509/expected.txt
@@ -0,0 +1,3 @@
+01:Verified
+02:Verified
+03:Verified \ No newline at end of file
diff --git a/src/tests/test_x509_path.cpp b/src/tests/test_x509_path.cpp
index 5fc20e3d7..e7cd9c18c 100644
--- a/src/tests/test_x509_path.cpp
+++ b/src/tests/test_x509_path.cpp
@@ -240,6 +240,84 @@ std::vector<Test::Result> NIST_Path_Validation_Tests::run()
BOTAN_REGISTER_TEST("x509_path_nist", NIST_Path_Validation_Tests);
+class Extended_Path_Validation_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override;
+ };
+
+std::vector<Test::Result> Extended_Path_Validation_Tests::run()
+ {
+ std::vector<Test::Result> results;
+
+ const std::string extended_x509_test_dir = Test::data_dir() + "/extended_x509";
+
+ try
+ {
+ // Do nothing, just test filesystem access
+ Botan::get_files_recursive(extended_x509_test_dir);
+ }
+ catch(Botan::No_Filesystem_Access&)
+ {
+ Test::Result result("Extended x509 path validation");
+ result.test_note("Skipping due to missing filesystem access");
+ results.push_back(result);
+ return results;
+ }
+
+ std::map<std::string, std::string> expected =
+ read_results(Test::data_file("extended_x509/expected.txt"));
+
+ for(auto i = expected.begin(); i != expected.end(); ++i)
+ {
+ const std::string test_name = i->first;
+ const std::string expected_result = i->second;
+
+ const std::string test_dir = extended_x509_test_dir + "/" + test_name;
+
+ Test::Result result("Extended X509 path validation");
+ result.start_timer();
+
+ const std::vector<std::string> all_files = Botan::get_files_recursive(test_dir);
+
+ if(all_files.empty())
+ {
+ result.test_failure("No test files found in " + test_dir);
+ results.push_back(result);
+ continue;
+ }
+
+ Botan::Certificate_Store_In_Memory store;
+
+ for(auto const& file : all_files)
+ {
+ if(file.find(".crt") != std::string::npos && file != "end.crt")
+ {
+ store.add_certificate(Botan::X509_Certificate(file));
+ }
+ }
+
+ Botan::X509_Certificate end_user(test_dir + "/end.crt");
+
+ Botan::Path_Validation_Restrictions restrictions;
+ Botan::Path_Validation_Result validation_result =
+ Botan::x509_path_validate(end_user,
+ restrictions,
+ store);
+
+ result.test_eq(test_name + " path validation result",
+ validation_result.result_string(),
+ expected_result);
+
+ result.end_timer();
+ results.push_back(result);
+ }
+
+ return results;
+ }
+
+BOTAN_REGISTER_TEST("x509_path_extended", Extended_Path_Validation_Tests);
+
#endif
}