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;
}
Aggregations