Skip to content

Commit 13af45d

Browse files
committed
PGPOnePassSignature: When verifying against signature: Compare salt value
1 parent 18152f9 commit 13af45d

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

pg/src/main/java/org/bouncycastle/openpgp/PGPOnePassSignature.java

+16
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.bouncycastle.openpgp.operator.PGPContentVerifier;
1414
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder;
1515
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
16+
import org.bouncycastle.util.Arrays;
1617

1718
/**
1819
* A one pass signature object.
@@ -113,6 +114,8 @@ public boolean verify(
113114
PGPSignature pgpSig)
114115
throws PGPException
115116
{
117+
compareSalt(pgpSig);
118+
116119
try
117120
{
118121
sigOut.write(pgpSig.getSignatureTrailer());
@@ -127,6 +130,19 @@ public boolean verify(
127130
return verifier.verify(pgpSig.getSignature());
128131
}
129132

133+
private void compareSalt(PGPSignature signature)
134+
throws PGPException
135+
{
136+
if (version != SignaturePacket.VERSION_6)
137+
{
138+
return;
139+
}
140+
if (!Arrays.constantTimeAreEqual(getSalt(), signature.getSalt()))
141+
{
142+
throw new PGPException("Salt in OnePassSignaturePacket does not match salt in SignaturePacket.");
143+
}
144+
}
145+
130146
/**
131147
* Return the packet version.
132148
*

pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java

+5
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ private PGPSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] p
470470
return null;
471471
}
472472

473+
byte[] getSalt()
474+
{
475+
return sigPck.getSalt();
476+
}
477+
473478
public byte[] getSignature()
474479
throws PGPException
475480
{

pg/src/test/java/org/bouncycastle/openpgp/test/PGPV6SignatureTest.java

+54
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public void performTest()
7171

7272
verifyingSignatureWithMismatchedSaltSizeFails();
7373
verifyingOPSWithMismatchedSaltSizeFails();
74+
verifyingInlineSignatureWithSignatureSaltValueMismatchFails();
7475
}
7576

7677
private void verifyV6DirectKeySignatureTestVector()
@@ -292,6 +293,59 @@ private void verifyingOPSWithMismatchedSaltSizeFails()
292293
}
293294
}
294295

296+
private void verifyingInlineSignatureWithSignatureSaltValueMismatchFails()
297+
throws IOException, PGPException
298+
{
299+
String ARMORED_MSG = "-----BEGIN PGP MESSAGE-----\n" +
300+
"\n" +
301+
"xEYGAQobIMcgFZRFzyKmYrqqNES9B0geVN5TZ6Wct6aUrITCuFyeyxhsTwYJppfk\n" +
302+
"1S36bHIrDB8eJ8GKVnCPZSXsJ7rZrMkAyxR1AAAAAABIZWxsbywgV29ybGQhCsKY\n" +
303+
"BgEbCgAAACkioQbLGGxPBgmml+TVLfpscisMHx4nwYpWcI9lJewnutmsyQWCZoJv\n" +
304+
"WQAAAAAkFSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItltzKi2NN+\n" +
305+
"XNJISXQ0X0f4TppBoHbpmwc5YCTIv2+vDZPI+tjzXL9m2e1jrqqaUMEwQ+Zy8B+K\n" +
306+
"LC4rA6Gh2gY=\n" +
307+
"=KRD3\n" +
308+
"-----END PGP MESSAGE-----";
309+
310+
ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes(StandardCharsets.UTF_8));
311+
ArmoredInputStream aIn = new ArmoredInputStream(bIn);
312+
BCPGInputStream pIn = new BCPGInputStream(aIn);
313+
PGPObjectFactory objFac = new BcPGPObjectFactory(pIn);
314+
PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject();
315+
PGPPublicKey signingPubKey = secretKeys.getPublicKey();
316+
317+
bIn = new ByteArrayInputStream(ARMORED_MSG.getBytes(StandardCharsets.UTF_8));
318+
aIn = new ArmoredInputStream(bIn);
319+
pIn = new BCPGInputStream(aIn);
320+
objFac = new BcPGPObjectFactory(pIn);
321+
322+
PGPOnePassSignatureList opsList = (PGPOnePassSignatureList) objFac.nextObject();
323+
PGPOnePassSignature ops = opsList.get(0);
324+
isEncodingEqual("OPS salt MUST match our expectations.",
325+
Hex.decode("C720159445CF22A662BAAA3444BD07481E54DE5367A59CB7A694AC84C2B85C9E"),
326+
ops.getSalt());
327+
328+
ops.init(new BcPGPContentVerifierBuilderProvider(), signingPubKey);
329+
330+
PGPLiteralData lit = (PGPLiteralData) objFac.nextObject();
331+
ByteArrayOutputStream plainOut = new ByteArrayOutputStream();
332+
Streams.pipeAll(lit.getDataStream(), plainOut);
333+
334+
ops.update(plainOut.toByteArray());
335+
PGPSignatureList sigList = (PGPSignatureList) objFac.nextObject();
336+
PGPSignature sig = sigList.get(0);
337+
338+
try
339+
{
340+
ops.verify(sig);
341+
fail("Verifying signature with mismatched salt MUST fail.");
342+
}
343+
catch (PGPException e)
344+
{
345+
// expected
346+
}
347+
}
348+
295349
public static void main(String[] args)
296350
{
297351
runTest(new PGPV6SignatureTest());

0 commit comments

Comments
 (0)