package org.jivesoftware.openfire.keystore;
import org.jivesoftware.util.CertificateManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.cert.*;
import java.util.*;
/**
* A wrapper class for a store of certificates, its metadata (password, location) and related functionality that is
* used to <em>verify</em> credentials, a <em>trust store</em>
*
* The trust store should only contain certificates for the "most-trusted" Certificate Authorities (the store should not
* contain Intermediates"). These certificates are referred to as "Trust Anchors".
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class TrustStore extends CertificateStore
{
private static final Logger Log = LoggerFactory.getLogger( TrustStore.class );
public TrustStore( CertificateStoreConfiguration configuration, boolean createIfAbsent ) throws CertificateStoreConfigException
{
super( configuration, createIfAbsent );
}
/**
* Imports one certificate as a trust anchor into this store.
*
* Note that this method explicitly allows one to add invalid certificates.
*
* As this store is intended to contain certificates for "most-trusted" / root Certificate Authorities, this method
* will fail when the PEM representation contains more than one certificate.
*
* @param alias the name (key) under which the certificate is to be stored in the store (cannot be null or empty).
* @param pemRepresentation The PEM representation of the certificate to add (cannot be null or empty).
*/
public void installCertificate( String alias, String pemRepresentation ) throws CertificateStoreConfigException
{
// Input validation
if ( alias == null || alias.trim().isEmpty() )
{
throw new IllegalArgumentException( "Argument 'alias' cannot be null or an empty String." );
}
if ( pemRepresentation == null )
{
throw new IllegalArgumentException( "Argument 'pemRepresentation' cannot be null." );
}
alias = alias.trim();
// Check that there is a certificate for the specified alias
try
{
if ( store.containsAlias( alias ) )
{
throw new CertificateStoreConfigException( "Certificate already exists for alias: " + alias );
}
// From their PEM representation, parse the certificates.
final Collection<X509Certificate> certificates = CertificateManager.parseCertificates( pemRepresentation );
if ( certificates.isEmpty() ) {
throw new CertificateStoreConfigException( "No certificate was found in the input.");
}
if ( certificates.size() != 1 ) {
throw new CertificateStoreConfigException( "More than one certificate was found in the input." );
}
final X509Certificate certificate = certificates.iterator().next();
store.setCertificateEntry(alias, certificate);
persist();
}
catch ( CertificateException | KeyStoreException | IOException e )
{
throw new CertificateStoreConfigException( "Unable to install a certificate into a trust store.", e );
}
finally
{
reload(); // re-initialize store.
}
// TODO Notify listeners that a new certificate has been added.
}
}