Search in sources :

Example 6 with CryptoException

use of org.bouncycastle.crypto.CryptoException in project candlepin by candlepin.

the class CrlFileUtil method updateCRLFile.

/**
 * Updates the specified CRL file by adding or removing entries. If both lists are either null
 * or empty, the CRL file will not be modified by this method. If the file does not exist or
 * appears to be empty, it will be initialized before processing the lists.
 *
 * @param file
 *  The CRL file to update
 *
 * @param revoke
 *  A collection of serials to revoke (add)
 *
 * @param unrevoke
 *  A collection of serials to unrevoke (remove)
 *
 * @throws IOException
 *  if an IO error occurs while updating the CRL file
 */
public void updateCRLFile(File file, final Collection<BigInteger> revoke, final Collection<BigInteger> unrevoke) throws IOException {
    if (!file.exists() || file.length() == 0) {
        this.initializeCRLFile(file, revoke);
        return;
    }
    File strippedFile = stripCRLFile(file);
    InputStream input = null;
    InputStream reaper = null;
    BufferedOutputStream output = null;
    OutputStream filter = null;
    OutputStream encoder = null;
    try {
        // Impl note:
        // Due to the way the X509CRLStreamWriter works (and the DER format in general), we have
        // to make two passes through the file.
        input = new Base64InputStream(new FileInputStream(strippedFile));
        reaper = new Base64InputStream(new FileInputStream(strippedFile));
        // Note: This will break if we ever stop using RSA keys
        PrivateKey key = this.certificateReader.getCaKey();
        X509CRLStreamWriter writer = new X509CRLStreamWriter(input, (RSAPrivateKey) key, this.certificateReader.getCACert());
        // Add new entries
        if (revoke != null) {
            Date now = new Date();
            for (BigInteger serial : revoke) {
                writer.add(serial, now, CRLReason.privilegeWithdrawn);
            }
        }
        // or we could miss cases where we have entries to remove, but nothing to add.
        if (unrevoke != null && !unrevoke.isEmpty()) {
            writer.preScan(reaper, new CRLEntryValidator() {

                public boolean shouldDelete(CRLEntry entry) {
                    BigInteger certSerial = entry.getUserCertificate().getValue();
                    return unrevoke.contains(certSerial);
                }
            });
        } else {
            writer.preScan(reaper);
        }
        writer.setSigningAlgorithm(PKIUtility.SIGNATURE_ALGO);
        // Verify we actually have work to do now
        if (writer.hasChangesQueued()) {
            output = new BufferedOutputStream(new FileOutputStream(file));
            filter = new FilterOutputStream(output) {

                private boolean needsLineBreak = true;

                public void write(int b) throws IOException {
                    this.needsLineBreak = (b != (byte) '\n');
                    super.write(b);
                }

                public void write(byte[] buffer) throws IOException {
                    this.needsLineBreak = (buffer[buffer.length - 1] != (byte) '\n');
                    super.write(buffer);
                }

                public void write(byte[] buffer, int off, int len) throws IOException {
                    this.needsLineBreak = (buffer[off + len - 1] != (byte) '\n');
                    super.write(buffer, off, len);
                }

                public void close() throws IOException {
                    if (this.needsLineBreak) {
                        super.write((int) '\n');
                        this.needsLineBreak = false;
                    }
                // Impl note:
                // We're intentionally not propagating the call here.
                }
            };
            encoder = new Base64OutputStream(filter, true, 76, new byte[] { (byte) '\n' });
            output.write("-----BEGIN X509 CRL-----\n".getBytes());
            writer.lock();
            writer.write(encoder);
            encoder.close();
            filter.close();
            output.write("-----END X509 CRL-----\n".getBytes());
            output.close();
        }
    } catch (GeneralSecurityException e) {
        // This should never actually happen
        log.error("Unexpected security error occurred while retrieving CA key", e);
    } catch (CryptoException e) {
        // Something went horribly wrong with the stream writer
        log.error("Unexpected error occurred while writing new CRL file", e);
    } finally {
        for (Closeable stream : Arrays.asList(encoder, output, reaper, input)) {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    log.error("Unexpected exception occurred while closing stream: {}", stream, e);
                }
            }
        }
        if (!strippedFile.delete()) {
            log.error("Unable to delete temporary CRL file: {}", strippedFile);
        }
    }
}
Also used : RSAPrivateKey(java.security.interfaces.RSAPrivateKey) PrivateKey(java.security.PrivateKey) FileInputStream(java.io.FileInputStream) Base64InputStream(org.apache.commons.codec.binary.Base64InputStream) InputStream(java.io.InputStream) BufferedOutputStream(java.io.BufferedOutputStream) Base64OutputStream(org.apache.commons.codec.binary.Base64OutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FilterOutputStream(java.io.FilterOutputStream) GeneralSecurityException(java.security.GeneralSecurityException) Closeable(java.io.Closeable) CRLEntry(org.bouncycastle.asn1.x509.TBSCertList.CRLEntry) IOException(java.io.IOException) Base64OutputStream(org.apache.commons.codec.binary.Base64OutputStream) FileInputStream(java.io.FileInputStream) Date(java.util.Date) FileOutputStream(java.io.FileOutputStream) BigInteger(java.math.BigInteger) Base64InputStream(org.apache.commons.codec.binary.Base64InputStream) FilterOutputStream(java.io.FilterOutputStream) CryptoException(org.bouncycastle.crypto.CryptoException) File(java.io.File) BufferedOutputStream(java.io.BufferedOutputStream)

Aggregations

CryptoException (org.bouncycastle.crypto.CryptoException)6 IOException (java.io.IOException)4 BigInteger (java.math.BigInteger)2 PrivateKey (java.security.PrivateKey)2 P11TokenException (org.xipki.security.exception.P11TokenException)2 XiSecurityException (org.xipki.security.exception.XiSecurityException)2 BufferedOutputStream (java.io.BufferedOutputStream)1 Closeable (java.io.Closeable)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 FilterOutputStream (java.io.FilterOutputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 StringReader (java.io.StringReader)1 GeneralSecurityException (java.security.GeneralSecurityException)1 KeyFactory (java.security.KeyFactory)1 KeyPair (java.security.KeyPair)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 PublicKey (java.security.PublicKey)1