public synchronized void setSignature()

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());
        }
    }