Skip to content

Commit c591392

Browse files
committed
Add AbstractPublicKeyDataDecryptorFactory with common methods
1 parent f81a5dc commit c591392

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.bouncycastle.openpgp.operator;
2+
3+
import org.bouncycastle.bcpg.InputStreamPacket;
4+
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
5+
import org.bouncycastle.bcpg.PublicKeyEncSessionPacket;
6+
import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket;
7+
import org.bouncycastle.bcpg.X25519PublicBCPGKey;
8+
import org.bouncycastle.bcpg.X448PublicBCPGKey;
9+
import org.bouncycastle.openpgp.PGPException;
10+
import org.bouncycastle.util.Arrays;
11+
12+
public abstract class AbstractPublicKeyDataDecryptorFactory
13+
implements PublicKeyDataDecryptorFactory
14+
{
15+
16+
protected byte[] prependSKAlgorithmToSessionData(PublicKeyEncSessionPacket pkesk,
17+
InputStreamPacket encData,
18+
byte[] decryptedSessionData)
19+
throws PGPException
20+
{
21+
// V6 PKESK packets do not include the session key algorithm, so source it from the SEIPD2 instead
22+
if (!containsSKAlg(pkesk.getVersion()))
23+
{
24+
if (!(encData instanceof SymmetricEncIntegrityPacket) ||
25+
((SymmetricEncIntegrityPacket) encData).getVersion() != SymmetricEncIntegrityPacket.VERSION_2)
26+
{
27+
throw new PGPException("v6 PKESK packet MUST precede v2 SEIPD packet");
28+
}
29+
30+
SymmetricEncIntegrityPacket seipd2 = (SymmetricEncIntegrityPacket) encData;
31+
return Arrays.prepend(decryptedSessionData,
32+
(byte) (seipd2.getCipherAlgorithm() & 0xff));
33+
}
34+
// V3 PKESK does store the session key algorithm either encrypted or unencrypted, depending on the PK algorithm
35+
else
36+
{
37+
switch (pkesk.getAlgorithm())
38+
{
39+
case PublicKeyAlgorithmTags.X25519:
40+
// X25519 does not encrypt SK algorithm
41+
return Arrays.prepend(decryptedSessionData,
42+
pkesk.getEncSessionKey()[0][X25519PublicBCPGKey.LENGTH + 1]);
43+
case PublicKeyAlgorithmTags.X448:
44+
// X448 does not encrypt SK algorithm
45+
return Arrays.prepend(decryptedSessionData,
46+
pkesk.getEncSessionKey()[0][X448PublicBCPGKey.LENGTH + 1]);
47+
default:
48+
// others already prepended session key algorithm to session key
49+
return decryptedSessionData;
50+
}
51+
}
52+
}
53+
54+
protected boolean containsSKAlg(int pkeskVersion)
55+
{
56+
return pkeskVersion != PublicKeyEncSessionPacket.VERSION_6;
57+
}
58+
59+
protected boolean confirmCheckSum(
60+
byte[] sessionInfo, int algorithm)
61+
{
62+
// X25519, X448 does not include a checksum
63+
if (algorithm == PublicKeyAlgorithmTags.X25519 || algorithm == PublicKeyAlgorithmTags.X448)
64+
{
65+
return true;
66+
}
67+
68+
int check = 0;
69+
for (int i = 1; i != sessionInfo.length - 2; i++)
70+
{
71+
check += sessionInfo[i] & 0xff;
72+
}
73+
74+
return (sessionInfo[sessionInfo.length - 2] == (byte)(check >> 8))
75+
&& (sessionInfo[sessionInfo.length - 1] == (byte)(check));
76+
}
77+
}

0 commit comments

Comments
 (0)