aboutsummaryrefslogtreecommitdiffstats
path: root/src/crypto/x509.c
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-02-13 16:27:31 +0000
committerMichael Brown <mcb30@ipxe.org>2024-02-14 16:40:05 +0000
commit3e721e0c0836588b64deb6e1c1befd08f0f02e71 (patch)
tree417c4347622771d4fb5183cf292a69e621826519 /src/crypto/x509.c
parente10dfe5dc7a5985333c85d6b196196b5cce9303a (diff)
downloadipxe-3e721e0c0836588b64deb6e1c1befd08f0f02e71.tar.gz
[crypto] Add x509_truncate() to truncate a certificate chain
Downloading a cross-signed certificate chain to partially replace (rather than simply extend) an existing chain will require the ability to discard all certificates after a specified link in the chain. Extract the relevant logic from x509_free_chain() and expose it separately as x509_truncate(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto/x509.c')
-rw-r--r--src/crypto/x509.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/crypto/x509.c b/src/crypto/x509.c
index 1f017eb03..92318093e 100644
--- a/src/crypto/x509.c
+++ b/src/crypto/x509.c
@@ -1603,19 +1603,12 @@ int x509_check_name ( struct x509_certificate *cert, const char *name ) {
static void x509_free_chain ( struct refcnt *refcnt ) {
struct x509_chain *chain =
container_of ( refcnt, struct x509_chain, refcnt );
- struct x509_link *link;
- struct x509_link *tmp;
DBGC2 ( chain, "X509 chain %p freed\n", chain );
- /* Free each link in the chain */
- list_for_each_entry_safe ( link, tmp, &chain->links, list ) {
- x509_put ( link->cert );
- list_del ( &link->list );
- free ( link );
- }
-
/* Free chain */
+ x509_truncate ( chain, NULL );
+ assert ( list_empty ( &chain->links ) );
free ( chain );
}
@@ -1697,6 +1690,27 @@ int x509_append_raw ( struct x509_chain *chain, const void *data,
}
/**
+ * Truncate X.509 certificate chain
+ *
+ * @v chain X.509 certificate chain
+ * @v link Link after which to truncate chain, or NULL
+ */
+void x509_truncate ( struct x509_chain *chain, struct x509_link *link ) {
+ struct x509_link *tmp;
+
+ /* Truncate entire chain if no link is specified */
+ if ( ! link )
+ link = list_entry ( &chain->links, struct x509_link, list );
+
+ /* Free each link in the chain */
+ list_for_each_entry_safe_continue ( link, tmp, &chain->links, list ) {
+ x509_put ( link->cert );
+ list_del ( &link->list );
+ free ( link );
+ }
+}
+
+/**
* Identify X.509 certificate by subject
*
* @v certs X.509 certificate list