public String replaceCertificate( String pemCertificates, String pemPrivateKey, String passPhrase ) throws CertificateStoreConfigException
    {
        if ( pemCertificates == null || pemCertificates.trim().isEmpty() )
        {
            throw new IllegalArgumentException( "Argument 'pemCertificates' cannot be null or an empty String." );
        }
        if ( pemPrivateKey == null || pemPrivateKey.trim().isEmpty() )
        {
            throw new IllegalArgumentException( "Argument 'pemPrivateKey' cannot be null or an empty String." );
        }
        pemCertificates = pemCertificates.trim();

        try
        {
            // From its PEM representation, parse the certificates.
            final Collection<X509Certificate> certificates = CertificateManager.parseCertificates( pemCertificates );
            if ( certificates.isEmpty() )
            {
                throw new CertificateStoreConfigException( "No certificate was found in the input." );
            }

            // Note that PKCS#7 does not require a specific order for the certificates in the file - ordering is needed.
            final List<X509Certificate> ordered = CertificateUtils.order( certificates );

            // Of the ordered chain, the first certificate should be for our domain.
            if ( !isForThisDomain( ordered.get( 0 ) ) )
            {
                throw new CertificateStoreConfigException( "The supplied certificate chain does not cover the domain of this XMPP service." );
            }

            // From its PEM representation (and pass phrase), parse the private key.
            final PrivateKey privateKey = CertificateManager.parsePrivateKey( pemPrivateKey, passPhrase );

            // All appears to be in order. Replace any entries in the store.
            removeAllDomainEntries();
            final String alias = generateUniqueAlias();
            store.setKeyEntry( alias, privateKey, configuration.getPassword(), ordered.toArray( new X509Certificate[ ordered.size() ] ) );

            persist();

            Log.info( "Replaced all private keys and corresponding certificate chains with a new private key and certificate chain." );

            return alias;
        }
        catch ( CertificateException | KeyStoreException | IOException e )
        {
            reload(); // reset state of the store.
            throw new CertificateStoreConfigException( "Unable to install a certificate into an identity store.", e );
        }

        // TODO Notify listeners that a new certificate has been replaced.
    }
Imports a certificate and the private key that was used to generate the certificate, replacing any previously
installed entries for the same domain.

This method will import the certificate and key in the store using a unique alias. This alias is returned.

This method will fail when the provided certificate does not match the domain of this XMPP service.

@param pemCertificates a PEM representation of the certificate or certificate chain (cannot be null or empty).
@param pemPrivateKey   a PEM representation of the private key (cannot be null or empty).
@param passPhrase      optional pass phrase (must be present if the private key is encrypted).
@return The alias that was used (never null).
@throws CertificateStoreConfigException if there was a problem replacing the certificate
xmppserver/src/main/java/org/jivesoftware/openfire/keystore/IdentityStore.java