Package org.candlepin.controller

Source Code of org.candlepin.controller.CrlGeneratorTest

/**
* Copyright (c) 2009 - 2012 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package org.candlepin.controller;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.candlepin.model.CertificateSerial;
import org.candlepin.model.CertificateSerialCurator;
import org.candlepin.pki.PKIReader;
import org.candlepin.pki.PKIUtility;
import org.candlepin.pki.X509CRLEntryWrapper;
import org.candlepin.pki.impl.BouncyCastlePKIUtility;
import org.candlepin.pki.impl.DefaultSubjectKeyIdentifierWriter;
import org.candlepin.util.Util;

import org.bouncycastle.asn1.x509.CRLNumber;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.x509.X509V2CRLGenerator;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.security.auth.x500.X500Principal;

/**
* CRLGeneratorTest
*/
@SuppressWarnings("deprecation")
@RunWith(MockitoJUnitRunner.class)
public class CrlGeneratorTest {

    private static final KeyPair KP = generateKP();
    private static final X509Certificate CERT = generateCertificate();

    @Mock private PKIReader pkiReader;
    @Mock private CertificateSerialCurator curator;
    private PKIUtility pkiUtility;

    private CrlGenerator generator;

    public static KeyPair generateKP() {
        KeyPairGenerator kpg;
        try {
            kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(2048);
            return kpg.generateKeyPair();
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    private static X509Certificate generateCertificate() {
        X500Principal principal = new X500Principal(generateFakePrincipal());
        X509V3CertificateGenerator gen = new X509V3CertificateGenerator();
        gen.setSerialNumber(BigInteger.TEN);
        gen.setNotBefore(Util.yesterday());
        gen.setNotAfter(Util.getFutureDate(2));
        gen.setSubjectDN(principal);
        gen.setIssuerDN(principal);
        gen.setPublicKey(KP.getPublic());
        gen.setSignatureAlgorithm("SHA1WITHRSA");
        try {
            return gen.generate(KP.getPrivate());
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String generateFakePrincipal() {
        return "CN=test, UID=" + UUID.randomUUID();
    }

    @Before
    public void init() throws Exception {
        this.pkiUtility = new BouncyCastlePKIUtility(pkiReader,
            new DefaultSubjectKeyIdentifierWriter());
        this.generator = new CrlGenerator(curator, pkiUtility);

        when(pkiReader.getCaKey()).thenReturn(KP.getPrivate());
        when(pkiReader.getCACert()).thenReturn(CERT);
    }

    @Test
    public void crlNumberWithNull() {
        assertEquals(BigInteger.ZERO, generator.getCRLNumber(null));
    }

    @Test
    public void crlNumberWithCert() throws Exception {
        X509V2CRLGenerator g = new X509V2CRLGenerator();
        g.setIssuerDN(new X500Principal("CN=test, UID=" + UUID.randomUUID()));
        g.setThisUpdate(new Date());
        g.setNextUpdate(Util.tomorrow());
        g.setSignatureAlgorithm("SHA1withRSA");
        g.addExtension(X509Extensions.CRLNumber, false,
            new CRLNumber(BigInteger.TEN));

        X509CRL x509crl = g.generate(KP.getPrivate());
        assertEquals(BigInteger.TEN, this.generator.getCRLNumber(x509crl));
    }

    @Test
    public void serialsTransfered() {
        List<CertificateSerial> serials = getStubCSList();

        when(this.curator.retrieveTobeCollectedSerials())
            .thenReturn(serials);
        List<X509CRLEntryWrapper> entries = this.generator
            .getNewSerialsToAppendAndSetThemConsumed();
        assertEquals(entries.size(), serials.size());
        verify(this.curator).saveOrUpdateAll(serials);
        for (int i = 0; i < serials.size(); i++) {
            CertificateSerial cs = serials.get(i);
            assertEquals(cs.getSerial(), entries.get(i).getSerialNumber());
        }
    }

    @Test
    public void serialsEmptyList() {
        when(this.curator.retrieveTobeCollectedSerials())
            .thenReturn(new ArrayList<CertificateSerial>());
        List<X509CRLEntryWrapper> entries = this.generator
            .getNewSerialsToAppendAndSetThemConsumed();
        assertEquals(0, entries.size());
    }

    @Test
    @SuppressWarnings("serial")
    public void emptyExpiredSerials() {
        Set<? extends X509CRLEntry> set = stubX509CRLEntries();

        when(this.curator.getExpiredSerials())
            .thenReturn(new ArrayList<CertificateSerial>() {
                {
                    add(stubCS(1L, new Date()));
                    add(stubCS(10L, new Date()));
                }
            });
        Set<? extends X509CRLEntry> result = this.generator.removeExpiredSerials(set);
        assertEquals(1, result.size());

        X509CRLEntry entry = result.iterator().next();
        assertEquals(BigInteger.ZERO, entry.getSerialNumber());
    }

    @Test
    @SuppressWarnings("serial")
    public void expiredSerials() {
        Set<? extends X509CRLEntry> set = stubX509CRLEntries();

        when(this.curator.getExpiredSerials())
            .thenReturn(new ArrayList<CertificateSerial>() {
                {
                    add(stubCS(12L, new Date()));
                    add(stubCS(13L, new Date()));
                }
            });
        Set<? extends X509CRLEntry> result = this.generator.removeExpiredSerials(set);
        assertEquals(set.size(), result.size());
    }

    @Test
    public void emptyRevocationsReturnsUntouched() throws Exception {
        // there's gotta be a way to reduce to a set of mocks

        KeyPair kp = CrlGeneratorTest.generateKP();
        X509V2CRLGenerator g = new X509V2CRLGenerator();
        g.setIssuerDN(new X500Principal("CN=test, UID=" + UUID.randomUUID()));
        g.setThisUpdate(new Date());
        g.setNextUpdate(Util.tomorrow());
        g.setSignatureAlgorithm("SHA1withRSA");
        g.addExtension(X509Extensions.CRLNumber, false,
            new CRLNumber(BigInteger.TEN));
        X509CRL x509crl = g.generate(kp.getPrivate());

        // now we need to remove one of those serials
        List<CertificateSerial> toremove = new ArrayList<CertificateSerial>() {
            {
                add(stubCS(100L, new Date()));
            }
        };

        X509CRL untouchedcrl = generator.removeEntries(x509crl, toremove);
        assertEquals(x509crl, untouchedcrl);
    }

    @Test
    @SuppressWarnings("serial")
    public void removeEntries() throws Exception {
        // there's gotta be a way to reduce to a set of mocks

        KeyPair kp = CrlGeneratorTest.generateKP();
        X509V2CRLGenerator g = new X509V2CRLGenerator();
        g.setIssuerDN(new X500Principal("CN=test, UID=" + UUID.randomUUID()));
        g.setThisUpdate(new Date());
        g.setNextUpdate(Util.tomorrow());
        g.setSignatureAlgorithm("SHA1withRSA");
        g.addExtension(X509Extensions.CRLNumber, false,
            new CRLNumber(BigInteger.TEN));
        X509CRL x509crl = g.generate(kp.getPrivate());

        List<CertificateSerial> serials = getStubCSList();
        List<X509CRLEntryWrapper> entries = Util.newList();
        for (CertificateSerial serial : serials) {
            entries.add(new X509CRLEntryWrapper(serial.getSerial(),
                new Date()));
            serial.setCollected(true);
        }

        x509crl = pkiUtility.createX509CRL(entries, BigInteger.TEN);
        assertEquals(3, x509crl.getRevokedCertificates().size());


        // now we need to remove one of those serials
        List<CertificateSerial> toremove = new ArrayList<CertificateSerial>() {
            {
                add(stubCS(100L, new Date()));
            }
        };

        X509CRL updatedcrl = generator.removeEntries(x509crl, toremove);
        Set<? extends X509CRLEntry> revoked = updatedcrl.getRevokedCertificates();
        assertEquals(2, revoked.size());
    }

    @Test
    public void updateCRLWithNullInput() {
        List<CertificateSerial> serials = getStubCSList();
        when(this.curator.retrieveTobeCollectedSerials())
            .thenReturn(serials);
        X509CRL x509crl = this.generator.syncCRLWithDB((X509CRL) null);
        verify(this.curator).deleteExpiredSerials();
        assertEquals(BigInteger.ONE, this.generator.getCRLNumber(x509crl));
        Set<? extends X509CRLEntry> entries = x509crl.getRevokedCertificates();
        Set<BigInteger> nos = Util.newSet();
        for (X509CRLEntry entry : entries) {
            nos.add(entry.getSerialNumber());
        }
        assertTrue(nos.contains(BigInteger.ONE));
        assertTrue(nos.contains(new BigInteger("100")));
        assertTrue(nos.contains(new BigInteger("1235465")));
    }

    @Test
    public void updateCRLWithErrorDeletingExpired() {
        List<CertificateSerial> serials = getStubCSList();
        when(this.curator.retrieveTobeCollectedSerials())
            .thenReturn(serials);
        when(this.curator.deleteExpiredSerials()).thenThrow(new RuntimeException());

        X509CRL x509crl = this.generator.syncCRLWithDB((X509CRL) null);
        Set<? extends X509CRLEntry> entries = x509crl.getRevokedCertificates();
        Set<BigInteger> nos = Util.newSet();
        for (X509CRLEntry entry : entries) {
            nos.add(entry.getSerialNumber());
        }
        assertTrue(nos.contains(BigInteger.ONE));
        assertTrue(nos.contains(new BigInteger("100")));
        assertTrue(nos.contains(new BigInteger("1235465")));
    }

    @Test
    @SuppressWarnings({ "unchecked", "serial", "rawtypes" })
    public void testUpdateCRLWithMockedCRL() {
        X509CRL oldCert = mock(X509CRL.class);
        Set<? extends X509CRLEntry> crls = stubX509CRLEntries(); //0, 1, 10,

        // byte array captured from previous runs - represents 1
        when(oldCert.getExtensionValue("2.5.29.20"))
            .thenReturn(new byte[] {4, 3, 2, 1, 1});
        when(oldCert.getRevokedCertificates())
            .thenReturn((Set) crls);
        when(this.curator.getExpiredSerials())
            .thenReturn(getStubCSList())//1, 100, 1235465
        when(this.curator.retrieveTobeCollectedSerials()) //1001, 1002
            .thenReturn(new ArrayList<CertificateSerial>() {
                {
                    add(stubCS(1001L, new Date()));
                    add(stubCS(1002L, new Date()));
                }
            });
        X509CRL newCRL = this.generator.syncCRLWithDB(oldCert);

        verify(this.curator, times(1)).retrieveTobeCollectedSerials();
        verify(this.curator, times(1)).deleteExpiredSerials();
        verify(this.curator, times(1)).getExpiredSerials();

        assertEquals(new BigInteger("2"), this.generator.getCRLNumber(newCRL));

        Set<? extends X509CRLEntry> entries = newCRL.getRevokedCertificates();
        Set<BigInteger> nos = Util.newSet();
        for (X509CRLEntry entry : entries) {
            nos.add(entry.getSerialNumber());
        }
        long [] expectedSerials = new long[] { 1001, 1002, 0, 10};
        assertEquals(nos.size(), expectedSerials.length);
        for (int i = 0; i < expectedSerials.length; i++) {
            nos.contains(Util.toBigInt(expectedSerials[i]));
        }
    }

    @Test
    public void decodeValue() throws Exception {
        // there's gotta be a way to reduce to a set of mocks
        KeyPair kp = CrlGeneratorTest.generateKP();
        X509V2CRLGenerator g = new X509V2CRLGenerator();
        g.setIssuerDN(new X500Principal("CN=test, UID=" + UUID.randomUUID()));
        g.setThisUpdate(new Date());
        g.setNextUpdate(Util.tomorrow());
        g.setSignatureAlgorithm("SHA1withRSA");
        g.addExtension(X509Extensions.CRLNumber, false,
            new CRLNumber(BigInteger.TEN));

        X509CRL x509crl = g.generate(kp.getPrivate());

        assertEquals("10", pkiUtility.decodeDERValue(x509crl.getExtensionValue(
            X509Extensions.CRLNumber.getId())));
    }

    @SuppressWarnings("serial")
    private List<CertificateSerial> getStubCSList() {
        return new ArrayList<CertificateSerial>() {
            {
                add(stubCS(1L, new Date()));
                add(stubCS(100L, new Date()));
                add(stubCS(1235465L, new Date()));
            }
        };
    }

    private CertificateSerial stubCS(Long id, Date expiration) {
        CertificateSerial cs = new CertificateSerial(id, expiration);
        cs.setCollected(false);
        return cs;
    }

    private Set<? extends X509CRLEntry> stubX509CRLEntries() {
        Set<X509CRLEntry> set = new LinkedHashSet<X509CRLEntry>();
        set.add(mockCRL(BigInteger.ONE, new Date()));
        set.add(mockCRL(BigInteger.TEN, new Date()));
        set.add(mockCRL(BigInteger.ZERO, new Date()));
        return set;
    }

    private X509CRLEntry mockCRL(BigInteger serial, Date dt) {
        X509CRLEntry entry = mock(X509CRLEntry.class);
        when(entry.getSerialNumber()).thenReturn(serial);
        when(entry.getRevocationDate()).thenReturn(dt);
        return entry;
    }
}
TOP

Related Classes of org.candlepin.controller.CrlGeneratorTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.