All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jivesoftware.openfire.keystore.CertificateStore Maven / Gradle / Ivy

The newest version!
package org.jivesoftware.openfire.keystore;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.jivesoftware.util.CertificateManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * A wrapper class for a Java store of certificates, its metadata (password, location) and related functionality.
 *
 * A subclass of this class exists for each of the two distinct types of key store.
 * 
    *
  • one that is used to provide credentials, an identity store, in {@link IdentityStore}
  • *
  • one that is used to verify credentials, a trust store, in {@link TrustStore}
  • *
* * Note that in Java terminology, an identity store is commonly referred to as a 'key store', while the same name is * also used to identify the generic certificate store. To have clear distinction between common denominator and each of * the specific types, this implementation uses the terms "certificate store", "identity store" and "trust store". * * @author Guus der Kinderen, [email protected] */ public abstract class CertificateStore { private static final Logger Log = LoggerFactory.getLogger( CertificateStore.class ); protected static final Provider PROVIDER = new BouncyCastleProvider(); static { // Add the BC provider to the list of security providers Security.addProvider( PROVIDER ); } protected final KeyStore store; protected final CertificateStoreConfiguration configuration; public CertificateStore( CertificateStoreConfiguration configuration, boolean createIfAbsent ) throws CertificateStoreConfigException { if (configuration == null) { throw new IllegalArgumentException( "Argument 'configuration' cannot be null." ); } this.configuration = configuration; try { final File file = configuration.getFile(); if ( createIfAbsent && !file.exists() ) { try ( final FileOutputStream os = new FileOutputStream( file.getPath() ) ) { store = KeyStore.getInstance( configuration.getType() ); store.load( null, configuration.getPassword() ); store.store( os, configuration.getPassword() ); } } else { try ( final FileInputStream is = new FileInputStream( file ) ) { store = KeyStore.getInstance( configuration.getType() ); store.load( is, configuration.getPassword() ); } } } catch ( IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException ex ) { throw new CertificateStoreConfigException( "Unable to load store of type '" + configuration.getType() + "' from file '" + configuration.getFile() + "'", ex ); } } /** * Reloads the content of the store from disk. Useful when the store content has been modified outside of the * Openfire process, or when changes that have not been persisted need to be undone. */ public void reload() throws CertificateStoreConfigException { try ( final FileInputStream is = new FileInputStream( configuration.getFile() ) ) { store.load( is, configuration.getPassword() ); CertificateManager.fireCertificateStoreChanged( this ); } catch ( IOException | NoSuchAlgorithmException | CertificateException ex ) { throw new CertificateStoreConfigException( "Unable to reload store in '" + configuration.getFile() + "'", ex ); } } /** * Saves the current state of the store to disk. Useful when certificates have been added or removed from the * store. */ public void persist() throws CertificateStoreConfigException { try ( final FileOutputStream os = new FileOutputStream( configuration.getFile() ) ) { store.store( os, configuration.getPassword() ); } catch ( NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException ex ) { throw new CertificateStoreConfigException( "Unable to save changes to store in '" + configuration.getFile() + "'", ex ); } } /** * Returns a collection of all x.509 certificates in this store. Certificates returned by this method can be of any * state (eg: invalid, on a revocation list, etc). * * @return A collection (possibly empty, never null) of all certificates in this store, mapped by their alias. */ public Map getAllCertificates() throws KeyStoreException { final Map results = new HashMap<>(); for ( final String alias : Collections.list( store.aliases() ) ) { final Certificate certificate = store.getCertificate( alias ); if ( !( certificate instanceof X509Certificate ) ) { continue; } results.put( alias, (X509Certificate) certificate ); } return results; } /** * Deletes an entry (by entry) in this store. All information related to this entry will be removed, including * certificates and keys. * * When the store does not contain an entry that matches the provided alias, this method does nothing. * * @param alias The alias for which to delete an entry (cannot be null or empty). */ public void delete( String alias ) throws CertificateStoreConfigException { // Input validation if ( alias == null || alias.trim().isEmpty() ) { throw new IllegalArgumentException( "Argument 'alias' cannot be null or an empty String." ); } try { if ( !store.containsAlias( alias ) ) { Log.info( "Unable to delete certificate for alias '" + alias + "' from store, as the store does not contain a certificate for that alias." ); return; } store.deleteEntry( alias ); persist(); } catch ( CertificateStoreConfigException | KeyStoreException e ) { reload(); // reset state of the store. throw new CertificateStoreConfigException( "Unable to install a certificate into an identity store.", e ); } } public KeyStore getStore() { return store; } public CertificateStoreConfiguration getConfiguration() { return configuration; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy