in jsign-core/src/main/java/net/jsign/mscab/MSCabinetFile.java [225:283]
public synchronized void setSignature(CMSSignedData signature) throws IOException {
byte[] content = signature.toASN1Structure().getEncoded("DER");
int shift = 0;
if (!header.isReservePresent()) {
shift = 4 + CABSignature.SIZE;
insert(channel, CFHeader.BASE_SIZE, new byte[shift]);
header.cbCFHeader = CABSignature.SIZE;
header.cbCabinet += shift;
header.coffFiles += shift;
header.flags |= CFHeader.FLAG_RESERVE_PRESENT;
header.abReserved = new byte[CABSignature.SIZE];
}
CABSignature cabsig = new CABSignature(header.abReserved);
cabsig.header = CABSignature.HEADER;
cabsig.offset = (int) header.cbCabinet;
cabsig.length = content.length;
header.abReserved = cabsig.array();
// rewrite the header
channel.position(0);
ByteBuffer buffer = ByteBuffer.allocate(header.getHeaderSize()).order(ByteOrder.LITTLE_ENDIAN);
header.write(buffer);
buffer.flip();
channel.write(buffer);
// skip the previous/next cabinet names
if (header.hasPreviousCabinet()) {
readNullTerminatedString(channel); // szCabinetPrev
readNullTerminatedString(channel); // szDiskPrev
}
if (header.hasNextCabinet()) {
readNullTerminatedString(channel); // szCabinetNext
readNullTerminatedString(channel); // szDiskNext
}
// shift the start offset of the CFFOLDER structures
for (int i = 0; i < header.cFolders; i++) {
long position = channel.position();
CFFolder folder = CFFolder.read(channel);
folder.coffCabStart += shift;
channel.position(position);
folder.write(channel);
}
// write the signature
channel.position(cabsig.offset);
channel.write(ByteBuffer.wrap(content));
// shrink the file if the new signature is shorter
if (channel.position() < channel.size()) {
channel.truncate(channel.position());
}
}