Skip to content

Commit

Permalink
Preserve the first structure of the cabinet file's reserve when signing
Browse files Browse the repository at this point in the history
  • Loading branch information
ebourg committed Jun 20, 2024
1 parent 90415fc commit 164ef54
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
13 changes: 9 additions & 4 deletions jsign-core/src/main/java/net/jsign/mscab/MSCabinetFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ public synchronized byte[] computeDigest(DigestAlgorithm digestAlgorithm) throws

CFReserve modifiedReserve = new CFReserve();
modifiedReserve.minSize = header.cbCFHeader;
if (header.reserve != null) {
modifiedReserve.structure1 = header.reserve.structure1;
}
modifiedReserve.structure2 = new byte[CABSignature.SIZE];

CFHeader modifiedHeader = new CFHeader(header);
Expand Down Expand Up @@ -194,9 +197,13 @@ public synchronized void setSignature(CMSSignedData signature) throws IOExceptio

int previousSize = header.getHeaderSize();

CFReserve reserve = new CFReserve();
reserve.minSize = header.cbCFHeader;
if (header.reserve != null) {
reserve.structure1 = header.reserve.structure1;
}

if (content.length > 0) {
CFReserve reserve = new CFReserve();
reserve.minSize = header.cbCFHeader;
reserve.structure2 = new byte[CABSignature.SIZE];

header.setReserve(reserve);
Expand All @@ -207,8 +214,6 @@ public synchronized void setSignature(CMSSignedData signature) throws IOExceptio

reserve.structure2 = cabsig.array();
} else {
CFReserve reserve = new CFReserve();
reserve.minSize = header.cbCFHeader;
reserve.structure2 = new byte[0];

header.setReserve(reserve);
Expand Down
33 changes: 33 additions & 0 deletions jsign-core/src/test/java/net/jsign/mscab/MSCabinetFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,39 @@ public void testCabinetWithSignatureInReserve() throws Exception {
}
}

@Test
public void testCabinetWithJunkInReserve() throws Exception {
File sourceFile = new File("target/test-classes/mscab/sample4.cab");
File targetFile = new File("target/test-classes/mscab/sample4-junk-in-reserve.cab");

FileUtils.copyFile(sourceFile, targetFile);

// inject junk in the reserve
try (SeekableByteChannel channel = Files.newByteChannel(targetFile.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE)) {
CFHeader header = new CFHeader();
header.read(channel);
header.reserve.structure1 = "Lorem ipsum".getBytes();
header.write(channel);
}

KeyStore keystore = new KeyStoreBuilder().keystore("target/test-classes/keystores/keystore.jks").storepass("password").build();
AuthenticodeSigner signer = new AuthenticodeSigner(keystore, "test", "password").withTimestamping(false);

try (MSCabinetFile file = new MSCabinetFile(targetFile)) {
file.setSignature(null);
signer.sign(file);
assertSigned(file, SHA256);
}

// check if the junk is still there
try (SeekableByteChannel channel = Files.newByteChannel(targetFile.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE)) {
CFHeader header = new CFHeader();
header.read(channel);
assertEquals("junk length", "Lorem ipsum".length(), header.reserve.structure1.length);
assertEquals("junk content", "Lorem ipsum", new String(header.reserve.structure1));
}
}

@Test
public void testRemoveSignature() throws Exception {
File sourceFile = new File("target/test-classes/mscab/sample1.cab");
Expand Down

0 comments on commit 164ef54

Please sign in to comment.