private static ResultHolder generateCertificateChainWithExpiredCertOnPosition(@Nullable final String subjectCommonName, final int certificateInChainThatIsExpired) throws Exception
    {
        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( KEY_ALGORITHM );
        keyPairGenerator.initialize( KEY_SIZE );

        // Root certificate (representing the CA) is self-signed.
        KeyPair subjectKeyPair = keyPairGenerator.generateKeyPair();
        KeyPair issuerKeyPair = subjectKeyPair;

        final X509Certificate[] result = new X509Certificate[ CHAIN_LENGTH ];
        for ( int i = CHAIN_LENGTH - 1 ; i >= 0; i-- )
        {
            boolean isValid = ( i != certificateInChainThatIsExpired ); // one certificate needs to be expired!
            result[ i ] = generateTestCertificate( i == 0 ? subjectCommonName : null, isValid, issuerKeyPair, subjectKeyPair, i );

            // Further away from the root CA, each certificate is issued by the previous subject.
            issuerKeyPair = subjectKeyPair;
            subjectKeyPair = keyPairGenerator.generateKeyPair();
        }

        // Note that the issuerKeyPair now holds the subjectKeyPair that was used last! SubjectKeyPair now holds an unused value.
        return new ResultHolder(issuerKeyPair, result);
    }
Generates a chain of certificates, identical to {@link #generateValidCertificateChain()}, with one exception:
one certificate in the chain (identified by its number in the chain, provided by the second argument) is expired.

@param subjectCommonName The CN value to use in the end-entity certificate.
@param certificateInChainThatIsExpired certificate position in chain that is expired (zero-based).
@return an array of certificates. Never null, never an empty array.
xmppserver/src/test/java/org/jivesoftware/openfire/keystore/KeystoreTestUtils.java