Skip to content

Commit 215145b

Browse files
author
gefeili
committed
Refactor on BcPublicKeyDataDecryptorFactory
1 parent bb2871d commit 215145b

File tree

1 file changed

+52
-64
lines changed

1 file changed

+52
-64
lines changed

pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.bouncycastle.crypto.BlockCipher;
2020
import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher;
2121
import org.bouncycastle.crypto.InvalidCipherTextException;
22+
import org.bouncycastle.crypto.RawAgreement;
2223
import org.bouncycastle.crypto.Wrapper;
2324
import org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
2425
import org.bouncycastle.crypto.agreement.X25519Agreement;
@@ -67,11 +68,27 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkes
6768

6869
if (keyAlgorithm == PublicKeyAlgorithmTags.X25519)
6970
{
70-
return recoverX25519SessionData(secKeyData, privKey, containsSKAlg);
71+
return getSessionData(secKeyData[0], privKey, X25519PublicBCPGKey.LENGTH, HashAlgorithmTags.SHA256,
72+
SymmetricKeyAlgorithmTags.AES_128, new X25519Agreement(), "X25519", new PublicKeyParametersOperation()
73+
{
74+
@Override
75+
public AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff)
76+
{
77+
return new X25519PublicKeyParameters(pEnc, 0);
78+
}
79+
});
7180
}
7281
else if (keyAlgorithm == PublicKeyAlgorithmTags.X448)
7382
{
74-
return recoverX448SessionData(secKeyData, privKey, containsSKAlg);
83+
return getSessionData(secKeyData[0], privKey, X448PublicBCPGKey.LENGTH, HashAlgorithmTags.SHA512,
84+
SymmetricKeyAlgorithmTags.AES_256, new X448Agreement(), "X448", new PublicKeyParametersOperation()
85+
{
86+
@Override
87+
public AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff)
88+
{
89+
return new X448PublicKeyParameters(pEnc, 0);
90+
}
91+
});
7592
}
7693
else if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH)
7794
{
@@ -113,20 +130,19 @@ private byte[] recoverElgamalSessionData(int keyAlgorithm,
113130
byte[] tmp = new byte[size];
114131

115132
byte[] bi = secKeyData[0]; // encoded MPI
116-
if (bi.length - 2 > size) // leading Zero? Shouldn't happen but...
117-
{
118-
c1.processBytes(bi, 3, bi.length - 3);
119-
}
120-
else
121-
{
122-
System.arraycopy(bi, 2, tmp, tmp.length - (bi.length - 2), bi.length - 2);
123-
c1.processBytes(tmp, 0, tmp.length);
124-
}
133+
procoessBytesFromElgamalSessionData(c1, size, tmp, bi);
125134

126135
bi = secKeyData[1]; // encoded MPI
127136
Arrays.fill(tmp, (byte)0);
128137

129-
if (bi.length - 2 > size) // leading Zero? Shouldn't happen but...
138+
procoessBytesFromElgamalSessionData(c1, size, tmp, bi);
139+
140+
return c1.doFinal();
141+
}
142+
143+
private void procoessBytesFromElgamalSessionData(BufferedAsymmetricBlockCipher c1, int size, byte[] tmp, byte[] bi)
144+
{
145+
if (bi.length - 2 > size) // leading Zero? Shouldn't happen but...
130146
{
131147
c1.processBytes(bi, 3, bi.length - 3);
132148
}
@@ -135,8 +151,6 @@ private byte[] recoverElgamalSessionData(int keyAlgorithm,
135151
System.arraycopy(bi, 2, tmp, tmp.length - (bi.length - 2), bi.length - 2);
136152
c1.processBytes(tmp, 0, tmp.length);
137153
}
138-
139-
return c1.doFinal();
140154
}
141155

142156
private byte[] recoverRSASessionData(int keyAlgorithm,
@@ -217,56 +231,6 @@ else if (ecPubKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448))
217231
return PGPPad.unpadSessionData(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key));
218232
}
219233

220-
private byte[] recoverX25519SessionData(byte[][] secKeyData, AsymmetricKeyParameter privKey, boolean includesSesKeyAlg)
221-
throws PGPException, InvalidCipherTextException
222-
{
223-
byte[] enc = secKeyData[0];
224-
// 32 octets ephemeral key
225-
int pLen = X25519PublicBCPGKey.LENGTH;
226-
byte[] ephemeralKey = Arrays.copyOf(enc, pLen);
227-
228-
// size of following fields
229-
int size = enc[pLen] & 0xff;
230-
checkRange(pLen + 1 + size, enc);
231-
232-
// encrypted session key
233-
int sesKeyLen = size - (includesSesKeyAlg ? 1 : 0);
234-
int sesKeyOff = pLen + 1 + (includesSesKeyAlg ? 1 : 0);
235-
byte[] keyEnc = Arrays.copyOfRange(enc, sesKeyOff, sesKeyOff + sesKeyLen);
236-
237-
byte[] secret = BcUtil.getSecret(new X25519Agreement(), privKey, new X25519PublicKeyParameters(ephemeralKey, 0));
238-
239-
byte[] hkdfOut = RFC6637KDFCalculator.createKey(HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128,
240-
Arrays.concatenate(ephemeralKey, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret),
241-
"OpenPGP X25519");
242-
243-
return unwrapSessionData(keyEnc, SymmetricKeyAlgorithmTags.AES_128, new KeyParameter(hkdfOut));
244-
}
245-
246-
private byte[] recoverX448SessionData(byte[][] secKeyData, AsymmetricKeyParameter privKey, boolean includesSesKeyAlg)
247-
throws PGPException, InvalidCipherTextException
248-
{
249-
byte[] enc = secKeyData[0];
250-
// 56 octets ephemeral key
251-
int pLen = X448PublicBCPGKey.LENGTH;
252-
byte[] ephemeralKey = Arrays.copyOf(enc, pLen);
253-
254-
// size of the following fields
255-
int size = enc[pLen] & 0xff;
256-
checkRange(pLen + 1 + size, enc);
257-
258-
// encrypted session key
259-
int sesKeyLen = size - (includesSesKeyAlg ? 1 : 0);
260-
int sesKeyOff = pLen + 1 + (includesSesKeyAlg ? 1 : 0);
261-
byte[] encSesKey = Arrays.copyOfRange(enc, sesKeyOff, sesKeyOff + sesKeyLen);
262-
263-
byte[] secret = BcUtil.getSecret(new X448Agreement(), privKey, new X448PublicKeyParameters(ephemeralKey, 0));
264-
KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256,
265-
Arrays.concatenate(ephemeralKey, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret), "OpenPGP X448"));
266-
267-
return unwrapSessionData(encSesKey, SymmetricKeyAlgorithmTags.AES_256, key);
268-
}
269-
270234
// OpenPGP v4
271235
@Override
272236
public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key)
@@ -293,6 +257,30 @@ public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, P
293257
return BcAEADUtil.createOpenPgpV6DataDecryptor(seipd, sessionKey);
294258
}
295259

260+
@FunctionalInterface
261+
private interface PublicKeyParametersOperation
262+
{
263+
AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff);
264+
}
265+
266+
private byte[] getSessionData(byte[] enc, AsymmetricKeyParameter privKey, int pLen, int hashAlgorithm, int symmetricKeyAlgorithm,
267+
RawAgreement agreement, String algorithmName, PublicKeyParametersOperation pkp)
268+
throws PGPException, InvalidCipherTextException
269+
{
270+
byte[] pEnc = new byte[pLen];
271+
byte[] keyEnc;
272+
System.arraycopy(enc, 0, pEnc, 0, pLen);
273+
int keyLen = enc[pLen] & 0xff;
274+
checkRange(pLen + 1 + keyLen, enc);
275+
keyEnc = new byte[keyLen - 1];
276+
System.arraycopy(enc, pLen + 2, keyEnc, 0, keyEnc.length);
277+
byte[] secret = BcUtil.getSecret(agreement, privKey, pkp.getPublicKeyParameters(pEnc, 0));
278+
KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(hashAlgorithm, symmetricKeyAlgorithm,
279+
Arrays.concatenate(pEnc, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret), "OpenPGP " + algorithmName));
280+
281+
return Arrays.prepend(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key), enc[pLen + 1]);
282+
}
283+
296284
private static byte[] unwrapSessionData(byte[] keyEnc, int symmetricKeyAlgorithm, KeyParameter key)
297285
throws PGPException, InvalidCipherTextException
298286
{

0 commit comments

Comments
 (0)