Search in sources :

Example 16 with CertificateList

use of org.bouncycastle.asn1.x509.CertificateList in project candlepin by candlepin.

the class X509CRLStreamWriter method handleHeader.

protected int handleHeader(OutputStream out) throws IOException {
    /* The length of an RSA signature is padded out to the length of the modulus
         * in bytes.  See http://stackoverflow.com/questions/6658728/rsa-signature-size
         *
         * If the original CRL was signed with a 2048 bit key and someone sends in a
         * 4096 bit key, we need to account for the discrepancy.
         */
    int newSigBytes = key.getModulus().bitLength() / 8;
    /* Now we need a byte array to figure out how long the new signature will
         * be when encoded.
         */
    byte[] dummySig = new byte[newSigBytes];
    Arrays.fill(dummySig, (byte) 0x00);
    this.newSigLength = new DERBitString(dummySig).getEncoded().length;
    int addedEntriesLength = 0;
    for (ASN1Sequence s : newEntries) {
        addedEntriesLength += s.getEncoded().length;
    }
    int topTag = readTag(crlIn, null);
    int topTagNo = readTagNumber(crlIn, topTag, null);
    int oldTotalLength = readLength(crlIn, null);
    // Now we are in the TBSCertList
    int tbsTag = readTag(crlIn, null);
    int tbsTagNo = readTagNumber(crlIn, tbsTag, null);
    int oldTbsLength = readLength(crlIn, null);
    /* We may need to adjust the overall length of the tbsCertList
         * based on changes in the revokedCertificates sequence, so we
         * will cache the tbsCertList data in this temporary byte stream.
         */
    ByteArrayOutputStream temp = new ByteArrayOutputStream();
    int tagNo;
    Date oldThisUpdate;
    boolean signatureReplaced = false;
    while (true) {
        int tag = readTag(crlIn, null);
        tagNo = readTagNumber(crlIn, tag, null);
        // then not worry with other sequences.
        if (tagNo == SEQUENCE && !signatureReplaced) {
            readAndReplaceSignatureAlgorithm(temp);
            signatureReplaced = true;
        } else if (tagNo == GENERALIZED_TIME || tagNo == UTC_TIME) {
            oldThisUpdate = readAndReplaceTime(temp, tagNo);
            break;
        } else {
            writeTag(temp, tag, tagNo);
            int length = echoLength(temp);
            echoValue(temp, length);
        }
    }
    // Now we have to deal with the potential for an optional nextUpdate field
    int tag = readTag(crlIn, null);
    tagNo = readTagNumber(crlIn, tag, null);
    if (tagNo == GENERALIZED_TIME || tagNo == UTC_TIME) {
        /* It would be possible to take in a desired nextUpdate in the constructor
             * but I'm not sure if the added complexity is worth it.
             */
        offsetNextUpdate(temp, tagNo, oldThisUpdate);
        echoTag(temp);
    } else {
        writeTag(temp, tag, tagNo);
    }
    /* Much like throwing a stone into a pond, as one sequence increases in
         * length the change can ripple out to parent sequences as more bytes are
         * required to encode the length.  For example, if we have a tbsCertList of
         * size 250 and a revokedCertificates list of size 100, the revokedCertificates
         * list size could increase by 6 with no change in the length bytes its sequence
         * requires.  However, 250 + 6 extra bytes equals a total length of 256 which
         * requires 2 bytes to encode instead of 1, thus changing the total length
         * of the CertificateList sequence.
         *
         * We account for these ripples with the xxxHeaderBytesDelta variables.
         */
    int revokedCertsLengthDelta = addedEntriesLength - deletedEntriesLength;
    int oldRevokedCertsLength = readLength(crlIn, null);
    int newRevokedCertsLength = oldRevokedCertsLength + revokedCertsLengthDelta;
    int revokedCertsHeaderBytesDelta = findHeaderBytesDelta(oldRevokedCertsLength, newRevokedCertsLength);
    int tbsCertListLengthDelta = revokedCertsLengthDelta + revokedCertsHeaderBytesDelta + extensionsDelta;
    int newTbsLength = oldTbsLength + tbsCertListLengthDelta;
    int tbsHeaderBytesDelta = findHeaderBytesDelta(oldTbsLength, newTbsLength);
    // newSigLength represents a DER encoded signature so it already contains the header bytes delta.
    int sigLengthDelta = newSigLength - oldSigLength;
    int totalLengthDelta = tbsCertListLengthDelta + tbsHeaderBytesDelta + sigLengthDelta;
    int newTotalLength = oldTotalLength + totalLengthDelta;
    /* NB: The top level sequence isn't part of the signature so its tag and
         * length do not go through the signer.
         */
    writeTag(out, topTag, topTagNo);
    writeLength(out, newTotalLength);
    writeTag(out, tbsTag, tbsTagNo, signer);
    writeLength(out, newTbsLength, signer);
    byte[] header = temp.toByteArray();
    temp.close();
    out.write(header);
    signer.getOutputStream().write(header, 0, header.length);
    writeLength(out, newRevokedCertsLength, signer);
    return oldRevokedCertsLength;
}
Also used : ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) DERBitString(org.bouncycastle.asn1.DERBitString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Date(java.util.Date)

Aggregations

CertificateList (org.bouncycastle.asn1.x509.CertificateList)10 IOException (java.io.IOException)6 CRLException (java.security.cert.CRLException)6 X509CRL (java.security.cert.X509CRL)5 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)5 Date (java.util.Date)4 DERSequence (org.bouncycastle.asn1.DERSequence)4 CertificateException (java.security.cert.CertificateException)3 ArrayList (java.util.ArrayList)3 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)3 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)3 X509CRLHolder (org.bouncycastle.cert.X509CRLHolder)3 OperationException (org.xipki.ca.api.OperationException)3 BigInteger (java.math.BigInteger)2 CRL (java.security.cert.CRL)2 X509Certificate (java.security.cert.X509Certificate)2 BerInputStream (org.apache.harmony.security.asn1.BerInputStream)2 ContentInfo (org.apache.harmony.security.pkcs7.ContentInfo)2 SignedData (org.apache.harmony.security.pkcs7.SignedData)2 CertificateList (org.apache.harmony.security.x509.CertificateList)2