diff --git a/src/crypto/certstore.c b/src/crypto/certstore.c index 9809413a..d0ef5c5d 100644 --- a/src/crypto/certstore.c +++ b/src/crypto/certstore.c @@ -152,6 +152,10 @@ void certstore_add ( struct x509_certificate *cert ) { */ void certstore_del ( struct x509_certificate *cert ) { + /* Ignore attempts to remove permanent certificates */ + if ( cert->flags & X509_FL_PERMANENT ) + return; + /* Remove certificate from store */ DBGC ( &certstore, "CERTSTORE removed certificate %s\n", x509_name ( cert ) ); @@ -171,11 +175,22 @@ static unsigned int certstore_discard ( void ) { * only reference is held by the store itself. */ list_for_each_entry_reverse ( cert, &certstore.links, store.list ) { - if ( cert->refcnt.count == 0 ) { - certstore_del ( cert ); - return 1; - } + + /* Skip certificates for which another reference is held */ + if ( cert->refcnt.count > 0 ) + continue; + + /* Skip certificates that were added at build time or + * added explicitly at run time. + */ + if ( cert->flags & ( X509_FL_PERMANENT | X509_FL_EXPLICIT ) ) + continue; + + /* Discard certificate */ + certstore_del ( cert ); + return 1; } + return 0; } diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h index 58f91c01..78eeafbf 100644 --- a/src/include/ipxe/x509.h +++ b/src/include/ipxe/x509.h @@ -220,6 +220,10 @@ struct x509_certificate { enum x509_flags { /** Certificate has been validated */ X509_FL_VALIDATED = 0x0001, + /** Certificate was added at build time */ + X509_FL_PERMANENT = 0x0002, + /** Certificate was added explicitly at run time */ + X509_FL_EXPLICIT = 0x0004, }; /**