Skip to content

Commit 4926064

Browse files
author
gefeili
committed
Refactor in PGPKeyEncryptionMethodGenerator.open
1 parent ee613a6 commit 4926064

File tree

3 files changed

+70
-278
lines changed

3 files changed

+70
-278
lines changed

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

Lines changed: 20 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,26 @@ else if (directS2K)
259259
PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(messageKey);
260260
digestCalc = dataEncryptor.getIntegrityCalculator();
261261
BCPGHeaderObject encOut;
262+
int version = (dataEncryptor instanceof PGPAEADDataEncryptor ? (isV5StyleAEAD ? 5 : 6) : 4); // OpenPGP v4, v5 or v6
263+
for (int i = 0; i < methods.size(); i++)
264+
{
265+
PGPKeyEncryptionMethodGenerator method = methods.get(i);
266+
if (method instanceof PBEKeyEncryptionMethodGenerator)
267+
{
268+
PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)method;
269+
mGen.setKekAlgorithm(mGen.getSessionKeyWrapperAlgorithm(defAlgorithm));
270+
if (version >= 5)
271+
{
272+
mGen.setAEADAlgorithm(dataEncryptorBuilder.getAeadAlgorithm());
273+
}
274+
pOut.writePacket(mGen.generate(version, sessionInfo));
275+
}
276+
else if (method instanceof PublicKeyKeyEncryptionMethodGenerator)
277+
{
278+
PublicKeyKeyEncryptionMethodGenerator mGen = (PublicKeyKeyEncryptionMethodGenerator)method;
279+
pOut.writePacket(mGen.generate(version != 6 ? PublicKeyEncSessionPacket.VERSION_3 : PublicKeyEncSessionPacket.VERSION_6, sessionInfo));
280+
}
281+
}
262282
try
263283
{
264284
// OpenPGP v5 or v6
@@ -269,25 +289,14 @@ else if (directS2K)
269289
// data is encrypted by AEAD Encrypted Data packet (rfc4880bis10), so write v5 SKESK packet
270290
if (isV5StyleAEAD)
271291
{
272-
for (int i = 0; i < methods.size(); i++)
273-
{
274-
PGPKeyEncryptionMethodGenerator method = methods.get(i);
275-
writeOpenPGPv5ESKPacket(method, sessionInfo);
276-
}
277292
byte[] iv = aeadDataEncryptor.getIV();
278293
encOut = new AEADEncDataPacket(
279294
dataEncryptorBuilder.getAlgorithm(), aeadDataEncryptor.getAEADAlgorithm(), aeadDataEncryptor.getChunkSize(), iv);
280295
ivOrSaltLen = iv.length;
281296
}
282297
else // data is encrypted by v2 SEIPD (AEAD), so write v6 SKESK packet
283298
{
284-
//https://www.rfc-editor.org/rfc/rfc9580.html#section-3.7.2.1 Table 2
285299
//AEAD(HKDF(S2K(passphrase), info), secrets, packetprefix)
286-
for (int i = 0; i < methods.size(); i++)
287-
{
288-
PGPKeyEncryptionMethodGenerator method = methods.get(i);
289-
writeOpenPGPv6ESKPacket(method, sessionInfo);
290-
}
291300
encOut = SymmetricEncIntegrityPacket.createVersion2Packet(
292301
dataEncryptorBuilder.getAlgorithm(),
293302
aeadDataEncryptor.getAEADAlgorithm(),
@@ -310,11 +319,6 @@ else if (directS2K)
310319
// OpenPGP v4
311320
else // data is encrypted by v1 SEIPD or SED packet, so write v4 SKESK packet
312321
{
313-
for (int i = 0; i < methods.size(); i++)
314-
{
315-
PGPKeyEncryptionMethodGenerator method = methods.get(i);
316-
writeOpenPGPv4ESKPacket(method, sessionInfo);
317-
}
318322
if (digestCalc != null)
319323
{
320324
encOut = SymmetricEncIntegrityPacket.createVersion1Packet();
@@ -368,89 +372,6 @@ else if (directS2K)
368372
}
369373
}
370374

371-
/**
372-
* Write out a {@link org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket#VERSION_4 v4 SKESK} or
373-
* {@link org.bouncycastle.bcpg.PublicKeyEncSessionPacket#VERSION_3 v3 PKESK} packet,
374-
* depending on the method generator. This method is used by what can be referred to as OpenPGP v4.
375-
*
376-
* @param m session key encryption method generator
377-
* @param sessionInfo session info
378-
* @throws IOException
379-
* @throws PGPException
380-
*/
381-
private void writeOpenPGPv4ESKPacket(PGPKeyEncryptionMethodGenerator m, byte[] sessionInfo)
382-
throws IOException, PGPException
383-
{
384-
if (m instanceof PBEKeyEncryptionMethodGenerator)
385-
{
386-
PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)m;
387-
ContainedPacket esk = mGen.setKekAlgorithm(mGen.getSessionKeyWrapperAlgorithm(defAlgorithm))
388-
.generate(SymmetricKeyEncSessionPacket.VERSION_4, sessionInfo);
389-
pOut.writePacket(esk);
390-
}
391-
else if (m instanceof PublicKeyKeyEncryptionMethodGenerator)
392-
{
393-
PublicKeyKeyEncryptionMethodGenerator mGen = (PublicKeyKeyEncryptionMethodGenerator)m;
394-
pOut.writePacket(mGen.generate(PublicKeyEncSessionPacket.VERSION_3, sessionInfo));
395-
}
396-
}
397-
398-
/**
399-
* Write out a {@link org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket#VERSION_5 v5 SKESK} or
400-
* {@link org.bouncycastle.bcpg.PublicKeyEncSessionPacket#VERSION_3 v3 PKESK} packet,
401-
* depending on the method generator. This method is used by LibrePGP only.
402-
*
403-
* @param m session key encryption method generator.
404-
* @param sessionInfo session info
405-
* @throws IOException
406-
* @throws PGPException
407-
*/
408-
private void writeOpenPGPv5ESKPacket(PGPKeyEncryptionMethodGenerator m, byte[] sessionInfo)
409-
throws IOException, PGPException
410-
{
411-
if (m instanceof PBEKeyEncryptionMethodGenerator)
412-
{
413-
PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)m;
414-
ContainedPacket esk = mGen.setKekAlgorithm(mGen.getSessionKeyWrapperAlgorithm(defAlgorithm))
415-
.setAEADAlgorithm(dataEncryptorBuilder.getAeadAlgorithm())
416-
.generate(SymmetricKeyEncSessionPacket.VERSION_5, sessionInfo);
417-
pOut.writePacket(esk);
418-
}
419-
else if (m instanceof PublicKeyKeyEncryptionMethodGenerator)
420-
{
421-
PublicKeyKeyEncryptionMethodGenerator mGen = (PublicKeyKeyEncryptionMethodGenerator)m;
422-
pOut.writePacket(mGen.generate(PublicKeyEncSessionPacket.VERSION_3, sessionInfo));
423-
}
424-
}
425-
426-
/**
427-
* Write out a {@link org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket#VERSION_6 v6 SKESK} or
428-
* {@link org.bouncycastle.bcpg.PublicKeyEncSessionPacket#VERSION_6 v6 PKESK} packet,
429-
* depending on the method generator. This method is used by what can be referred to as OpenPGP v6.
430-
*
431-
* @param m session key encryption method generator.
432-
* @param sessionInfo session info
433-
* @throws IOException
434-
* @throws PGPException
435-
*/
436-
private void writeOpenPGPv6ESKPacket(PGPKeyEncryptionMethodGenerator m, byte[] sessionInfo)
437-
throws IOException, PGPException
438-
{
439-
if (m instanceof PBEKeyEncryptionMethodGenerator)
440-
{
441-
PBEKeyEncryptionMethodGenerator mGen = (PBEKeyEncryptionMethodGenerator)m;
442-
ContainedPacket esk = mGen.setKekAlgorithm(mGen.getSessionKeyWrapperAlgorithm(defAlgorithm))
443-
.setAEADAlgorithm(dataEncryptorBuilder.getAeadAlgorithm())
444-
.generate(SymmetricKeyEncSessionPacket.VERSION_6, sessionInfo);
445-
pOut.writePacket(esk);
446-
}
447-
else if (m instanceof PublicKeyKeyEncryptionMethodGenerator)
448-
{
449-
PublicKeyKeyEncryptionMethodGenerator mGen = (PublicKeyKeyEncryptionMethodGenerator)m;
450-
pOut.writePacket(mGen.generate(PublicKeyEncSessionPacket.VERSION_6, sessionInfo));
451-
}
452-
}
453-
454375
/**
455376
* Create an OutputStream based on the configured methods to write a single encrypted object of
456377
* known length.

pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java

Lines changed: 30 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ public PBEKeyEncryptionMethodGenerator setSessionKeyWrapperAlgorithm(int wrapAlg
117117
return this;
118118
}
119119

120+
/**
121+
* the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used to wrap the session key
122+
* */
120123
public PBEKeyEncryptionMethodGenerator setKekAlgorithm(int kekAlgorithm)
121124
{
122125
this.kekAlgorithm = kekAlgorithm;
@@ -174,6 +177,33 @@ public byte[] getKey(int encAlgorithm)
174177
return PGPUtil.makeKeyFromPassPhrase(s2kDigestCalculator, encAlgorithm, s2k, passPhrase);
175178
}
176179

180+
/**
181+
* Generates a version 4 Symmetric-Key-Encrypted-Session-Key (SKESK) packet, encoding the encrypted
182+
* session-key for this method.
183+
* SKESKv4 packets are used by Symmetrically-Encrypted-Integrity-Protected-Data (SEIPD) packets
184+
* of version 1, or by (deprecated) Symmetrically-Encrypted-Data (SED) packets.
185+
* <p/>
186+
* Generates a version 5 Symmetric-Key-Encrypted-Session-Key (SKESK) packet, encoding the encrypted
187+
* session-key for this method.
188+
* SKESKv5 packets are used with {@link org.bouncycastle.bcpg.AEADEncDataPacket OCB-Encrypted Data (OED) packets}
189+
* only.
190+
* AEAD algorithm ID (MUST be {@link org.bouncycastle.bcpg.AEADAlgorithmTags#OCB})
191+
* <p/>
192+
* Generates a version 6 Symmetric-Key-Encrypted-Session-Key (SKESK) packet, encoding the encrypted
193+
* session-key for this method.
194+
* SKESKv6 packets are used with Symmetrically-Encrypted Integrity-Protected Data (SEIPD) packets of
195+
* version 2 only.
196+
* A SKESKv6 packet MUST NOT precede a SEIPDv1, OED or SED packet.
197+
* @param sessionInfo session data generated by the encrypted data generator.
198+
* @return a packet encoding the provided information and the configuration of this instance.
199+
* @throws PGPException if an error occurs constructing the packet.
200+
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-version-4-symmetric-key-enc">
201+
* RFC9580 - Symmetric-Key Encrypted Session-Key Packet version 4</a>
202+
* @see <a href="https://www.ietf.org/archive/id/draft-koch-librepgp-02.html#section-5.3-8">
203+
* LibrePGP - Symmetric-Key Encrypted Session-Key Packet version 5</a>
204+
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-version-6-symmetric-key-enc">
205+
* RFC9580 - Symmetric-Key Encrypted Session-Key Packet version 6</a>
206+
*/
177207
public ContainedPacket generate(int version, byte[] sessionInfo)
178208
throws PGPException
179209
{
@@ -230,119 +260,6 @@ else if (version == SymmetricKeyEncSessionPacket.VERSION_5 || version == Symmetr
230260
throw new PGPException("Unexpected version number");
231261
}
232262

233-
/**
234-
* Generates a version 4 Symmetric-Key-Encrypted-Session-Key (SKESK) packet, encoding the encrypted
235-
* session-key for this method.
236-
* SKESKv4 packets are used by Symmetrically-Encrypted-Integrity-Protected-Data (SEIPD) packets
237-
* of version 1, or by (deprecated) Symmetrically-Encrypted-Data (SED) packets.
238-
* You MUST NOT use them when producing SEIPDv2 packets (use {@link #generateV6(int, int, byte[])}
239-
* instead in that case).
240-
*
241-
* @param kekAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used to
242-
* wrap the session key
243-
* @param sessionInfo session data generated by the encrypted data generator.
244-
* @return a packet encoding the provided information and the configuration of this instance.
245-
* @throws PGPException if an error occurs constructing the packet.
246-
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-version-4-symmetric-key-enc">
247-
* RFC9580 - Symmetric-Key Encrypted Session-Key Packet version 4</a>
248-
*/
249-
public ContainedPacket generateV4(int kekAlgorithm, byte[] sessionInfo)
250-
throws PGPException
251-
{
252-
if (sessionInfo == null)
253-
{
254-
return SymmetricKeyEncSessionPacket.createV4Packet(kekAlgorithm, s2k, null);
255-
}
256-
257-
byte[] key = getKey(kekAlgorithm);
258-
//
259-
// the passed in session info has the an RSA/ElGamal checksum added to it, for PBE this is not included.
260-
//
261-
byte[] nSessionInfo = new byte[sessionInfo.length - 2];
262-
263-
System.arraycopy(sessionInfo, 0, nSessionInfo, 0, nSessionInfo.length);
264-
265-
return SymmetricKeyEncSessionPacket.createV4Packet(kekAlgorithm, s2k, encryptSessionInfo(kekAlgorithm, key, nSessionInfo));
266-
}
267-
268-
/**
269-
* Generates a version 5 Symmetric-Key-Encrypted-Session-Key (SKESK) packet, encoding the encrypted
270-
* session-key for this method.
271-
* SKESKv5 packets are used with {@link org.bouncycastle.bcpg.AEADEncDataPacket OCB-Encrypted Data (OED) packets}
272-
* only.
273-
*
274-
* @param kekAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used to
275-
* wrap the session key
276-
* @param aeadAlgorithm AEAD algorithm ID (MUST be {@link org.bouncycastle.bcpg.AEADAlgorithmTags#OCB})
277-
* @param sessionInfo session data generated by the encrypted data generator.
278-
* @return a packet encoding the provided information and the configuration of this instance.
279-
* @throws PGPException if an error occurs constructing the packet.
280-
* @see <a href="https://www.ietf.org/archive/id/draft-koch-librepgp-02.html#section-5.3-8">
281-
* LibrePGP - Symmetric-Key Encrypted Session-Key Packet version 5</a>
282-
*/
283-
public ContainedPacket generateV5(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo)
284-
throws PGPException
285-
{
286-
byte[] ikm = getKey(kekAlgorithm);
287-
byte[] info = new byte[]{
288-
(byte)0xC3,
289-
(byte)SymmetricKeyEncSessionPacket.VERSION_5,
290-
(byte)kekAlgorithm,
291-
(byte)aeadAlgorithm
292-
};
293-
294-
byte[] iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)];
295-
random.nextBytes(iv);
296-
297-
int tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm);
298-
byte[] sessionKey = getSessionKey(sessionInfo);
299-
byte[] eskAndTag = getEskAndTag(kekAlgorithm, aeadAlgorithm, sessionKey, ikm, iv, info);
300-
byte[] esk = Arrays.copyOfRange(eskAndTag, 0, eskAndTag.length - tagLen);
301-
byte[] tag = Arrays.copyOfRange(eskAndTag, esk.length, eskAndTag.length);
302-
303-
return SymmetricKeyEncSessionPacket.createV5Packet(kekAlgorithm, aeadAlgorithm, iv, s2k, esk, tag);
304-
}
305-
306-
/**
307-
* Generates a version 6 Symmetric-Key-Encrypted-Session-Key (SKESK) packet, encoding the encrypted
308-
* session-key for this method.
309-
* SKESKv6 packets are used with Symmetrically-Encrypted Integrity-Protected Data (SEIPD) packets of
310-
* version 2 only.
311-
* A SKESKv6 packet MUST NOT precede a SEIPDv1, OED or SED packet.
312-
*
313-
* @param kekAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used to
314-
* wrap the session key
315-
* @param aeadAlgorithm AEAD algorithm ID
316-
* @param sessionInfo session data generated by the encrypted data generator.
317-
* @return a packet encoding the provided information and the configuration of this instance.
318-
* @throws PGPException if an error occurs constructing the packet.
319-
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-version-6-symmetric-key-enc">
320-
* RFC9580 - Symmetric-Key Encrypted Session-Key Packet version 6</a>
321-
*/
322-
public ContainedPacket generateV6(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo)
323-
throws PGPException
324-
{
325-
byte[] ikm = getKey(kekAlgorithm);
326-
byte[] info = new byte[]{
327-
(byte)0xC3,
328-
(byte)SymmetricKeyEncSessionPacket.VERSION_6,
329-
(byte)kekAlgorithm,
330-
(byte)aeadAlgorithm
331-
};
332-
byte[] kek = generateV6KEK(kekAlgorithm, ikm, info);
333-
334-
byte[] iv = new byte[AEADUtils.getIVLength(aeadAlgorithm)];
335-
random.nextBytes(iv);
336-
337-
int tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm);
338-
byte[] sk = getSessionKey(sessionInfo);
339-
byte[] eskAndTag = getEskAndTag(kekAlgorithm, aeadAlgorithm, sk, kek, iv, info);
340-
byte[] esk = Arrays.copyOfRange(eskAndTag, 0, eskAndTag.length - tagLen);
341-
byte[] tag = Arrays.copyOfRange(eskAndTag, esk.length, eskAndTag.length);
342-
343-
return SymmetricKeyEncSessionPacket.createV6Packet(kekAlgorithm, aeadAlgorithm, iv, s2k, esk, tag);
344-
}
345-
346263
protected byte[] getSessionKey(byte[] sessionInfo)
347264
{
348265
byte[] sessionKey = new byte[sessionInfo.length - 3];

0 commit comments

Comments
 (0)