Skip to content

Commit fda929a

Browse files
committed
Greatly simplified SignatureVerifier and removed some resource-leaks
1 parent 7198574 commit fda929a

File tree

2 files changed

+50
-62
lines changed

2 files changed

+50
-62
lines changed

app/test/cc/arduino/contributions/GPGDetachedSignatureVerifierTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@ public class GPGDetachedSignatureVerifierTest {
4444
@Before
4545
public void setUp() throws Exception {
4646
verifier = new SignatureVerifier();
47+
File keyRingFile = new File(GPGDetachedSignatureVerifierTest.class.getResource("./test.public.gpg.key").getFile());
48+
verifier.setKeyRingFile(keyRingFile);
4749
}
4850

4951
@Test
5052
public void testSignatureSuccessfulVerification() throws Exception {
5153
File signedFile = new File(GPGDetachedSignatureVerifierTest.class.getResource("./package_index.json").getFile());
5254
File sign = new File(GPGDetachedSignatureVerifierTest.class.getResource("./package_index.json.sig").getFile());
53-
File publickKey = new File(GPGDetachedSignatureVerifierTest.class.getResource("./test.public.gpg.key").getFile());
54-
assertTrue(verifier.verify(signedFile, sign, publickKey));
55+
assertTrue(verifier.verify(signedFile, sign));
5556
}
5657

5758
@Test
5859
public void testSignatureFailingVerification() throws Exception {
5960
File fakeSignedFile = File.createTempFile("fakeSigned", "txt");
6061
fakeSignedFile.deleteOnExit();
6162
File sign = new File(GPGDetachedSignatureVerifierTest.class.getResource("./package_index.json.sig").getFile());
62-
File publickKey = new File(GPGDetachedSignatureVerifierTest.class.getResource("./test.public.gpg.key").getFile());
63-
assertFalse(verifier.verify(fakeSignedFile, sign, publickKey));
63+
assertFalse(verifier.verify(fakeSignedFile, sign));
6464
}
6565
}

arduino-core/src/cc/arduino/contributions/SignatureVerifier.java

Lines changed: 46 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,34 @@
2929

3030
package cc.arduino.contributions;
3131

32+
import java.io.File;
33+
import java.io.FileInputStream;
34+
import java.io.IOException;
35+
import java.io.InputStream;
36+
3237
import org.apache.commons.compress.utils.IOUtils;
33-
import org.bouncycastle.openpgp.*;
38+
import org.bouncycastle.openpgp.PGPException;
39+
import org.bouncycastle.openpgp.PGPObjectFactory;
40+
import org.bouncycastle.openpgp.PGPPublicKey;
41+
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
42+
import org.bouncycastle.openpgp.PGPSignature;
43+
import org.bouncycastle.openpgp.PGPSignatureList;
44+
import org.bouncycastle.openpgp.PGPUtil;
3445
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
3546
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
3647

3748
import processing.app.BaseNoGui;
3849

39-
import java.io.*;
40-
import java.util.Iterator;
41-
4250
public class SignatureVerifier {
4351

44-
private String keyId;
52+
private File keyRingFile;
4553

4654
public SignatureVerifier() {
47-
this("7F294291");
55+
keyRingFile = new File(BaseNoGui.getContentFile("lib"), "public.gpg.key");
4856
}
4957

50-
public SignatureVerifier(String keyId) {
51-
this.keyId = keyId;
58+
public void setKeyRingFile(File keyRingFile) {
59+
this.keyRingFile = keyRingFile;
5260
}
5361

5462
public boolean isSigned(File indexFile) {
@@ -58,7 +66,7 @@ public boolean isSigned(File indexFile) {
5866
}
5967

6068
try {
61-
return verify(indexFile, signature, new File(BaseNoGui.getContentFile("lib"), "public.gpg.key"));
69+
return verify(indexFile, signature);
6270
} catch (Exception e) {
6371
BaseNoGui.showWarning(e.getMessage(), e.getMessage(), e);
6472
return false;
@@ -67,76 +75,56 @@ public boolean isSigned(File indexFile) {
6775

6876
public boolean isSigned(File indexFile, File signature) {
6977
try {
70-
return verify(indexFile, signature, new File(BaseNoGui.getContentFile("lib"), "public.gpg.key"));
78+
return verify(indexFile, signature);
7179
} catch (Exception e) {
7280
BaseNoGui.showWarning(e.getMessage(), e.getMessage(), e);
7381
return false;
7482
}
7583
}
7684

77-
protected boolean verify(File signedFile, File signature, File publicKey) throws IOException {
78-
FileInputStream signatureInputStream = null;
79-
FileInputStream signedFileInputStream = null;
85+
protected boolean verify(File signedFile, File signatureFile) throws IOException {
8086
try {
81-
signatureInputStream = new FileInputStream(signature);
82-
PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(signatureInputStream, new BcKeyFingerprintCalculator());
83-
84-
Object nextObject;
85-
try {
86-
nextObject = pgpObjectFactory.nextObject();
87-
if (!(nextObject instanceof PGPSignatureList)) {
87+
// Read signature from signatureFile
88+
PGPSignature signature;
89+
try (FileInputStream in = new FileInputStream(signatureFile)) {
90+
PGPObjectFactory objFactory = new PGPObjectFactory(in, new BcKeyFingerprintCalculator());
91+
Object obj = objFactory.nextObject();
92+
if (!(obj instanceof PGPSignatureList)) {
93+
return false;
94+
}
95+
PGPSignatureList signatureList = (PGPSignatureList) obj;
96+
if (signatureList.size() != 1) {
8897
return false;
8998
}
90-
} catch (IOException e) {
99+
signature = signatureList.get(0);
100+
} catch (Exception e) {
91101
return false;
92102
}
93-
PGPSignatureList pgpSignatureList = (PGPSignatureList) nextObject;
94-
assert pgpSignatureList.size() == 1;
95-
PGPSignature pgpSignature = pgpSignatureList.get(0);
96-
97-
PGPPublicKey pgpPublicKey = readPublicKey(publicKey, keyId);
98103

99-
pgpSignature.init(new BcPGPContentVerifierBuilderProvider(), pgpPublicKey);
100-
signedFileInputStream = new FileInputStream(signedFile);
101-
pgpSignature.update(IOUtils.toByteArray(signedFileInputStream));
104+
// Extract public key from keyring
105+
PGPPublicKey pgpPublicKey = readPublicKey(signature.getKeyID());
102106

103-
return pgpSignature.verify();
107+
// Check signature
108+
signature.init(new BcPGPContentVerifierBuilderProvider(), pgpPublicKey);
109+
try (FileInputStream in = new FileInputStream(signedFile)) {
110+
signature.update(IOUtils.toByteArray(in));
111+
return signature.verify();
112+
}
104113
} catch (PGPException e) {
105114
throw new IOException(e);
106-
} finally {
107-
IOUtils.closeQuietly(signatureInputStream);
108-
IOUtils.closeQuietly(signedFileInputStream);
109115
}
110116
}
111117

112-
private PGPPublicKey readPublicKey(File file, String id) throws IOException, PGPException {
113-
InputStream keyIn = null;
114-
try {
115-
keyIn = new BufferedInputStream(new FileInputStream(file));
116-
return readPublicKey(keyIn, id);
117-
} finally {
118-
IOUtils.closeQuietly(keyIn);
119-
}
120-
}
121-
122-
private PGPPublicKey readPublicKey(InputStream input, String id) throws IOException, PGPException {
123-
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input), new BcKeyFingerprintCalculator());
124-
125-
Iterator<PGPPublicKeyRing> keyRingIter = pgpPub.getKeyRings();
126-
while (keyRingIter.hasNext()) {
127-
PGPPublicKeyRing keyRing = keyRingIter.next();
118+
private PGPPublicKey readPublicKey(long id) throws IOException, PGPException {
119+
try (InputStream in = PGPUtil.getDecoderStream(new FileInputStream(keyRingFile))) {
120+
PGPPublicKeyRingCollection pubRing = new PGPPublicKeyRingCollection(in, new BcKeyFingerprintCalculator());
128121

129-
Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
130-
while (keyIter.hasNext()) {
131-
PGPPublicKey key = keyIter.next();
132-
133-
if (Long.toHexString(key.getKeyID()).toUpperCase().endsWith(id)) {
134-
return key;
135-
}
122+
PGPPublicKey publicKey = pubRing.getPublicKey(id);
123+
if (publicKey == null) {
124+
throw new IllegalArgumentException("Can't find public key in key ring.");
136125
}
126+
return publicKey;
137127
}
138-
139-
throw new IllegalArgumentException("Can't find encryption key in key ring.");
140128
}
141129

142130
}

0 commit comments

Comments
 (0)