if (internalData) {
decrypt(signer, box); // MAC is checked during decryption
return tmpBB;
}
BadPaddingException reservedBPE = null;
int tagLen = signer.MAClen();
int cipheredLength = bb.remaining();
if (!box.isNullCipher()) {
// sanity check length of the ciphertext
if (!box.sanityCheck(tagLen, cipheredLength)) {
throw new BadPaddingException(
"ciphertext sanity check failed");
}
try {
// Note that the CipherBox.decrypt() does not change
// the capacity of the buffer.
box.decrypt(bb, tagLen);
} catch (BadPaddingException bpe) {
// RFC 2246 states that decryption_failed should be used
// for this purpose. However, that allows certain attacks,
// so we just send bad record MAC. We also need to make
// sure to always check the MAC to avoid a timing attack
// for the same issue. See paper by Vaudenay et al and the
// update in RFC 4346/5246.
//
// Failover to message authentication code checking.
reservedBPE = bpe;
} finally {
bb.rewind();
}
}
if (tagLen != 0) {
int macOffset = bb.limit() - tagLen;
// Note that although it is not necessary, we run the same MAC
// computation and comparison on the payload for both stream
// cipher and CBC block cipher.
if (bb.remaining() < tagLen) {
// negative data length, something is wrong
if (reservedBPE == null) {
reservedBPE = new BadPaddingException("bad record");
}
// set offset of the dummy MAC
macOffset = cipheredLength - tagLen;
bb.limit(cipheredLength);
}
// Run MAC computation and comparison on the payload.
if (checkMacTags(contentType(), bb, signer, false)) {
if (reservedBPE == null) {
reservedBPE = new BadPaddingException("bad record MAC");
}
}
// Run MAC computation and comparison on the remainder.
//