@@ -35,10 +35,9 @@ public class PGPPublicKeyEncryptedData
3535 }
3636
3737 private boolean confirmCheckSum (
38- byte [] sessionInfo )
38+ byte [] sessionInfo )
3939 {
4040 int check = 0 ;
41-
4241 for (int i = 1 ; i != sessionInfo .length - 2 ; i ++)
4342 {
4443 check += sessionInfo [i ] & 0xff ;
@@ -72,7 +71,7 @@ public int getSymmetricAlgorithm(
7271 {
7372 if (keyData .getVersion () == PublicKeyEncSessionPacket .VERSION_3 )
7473 {
75- byte [] plain = dataDecryptorFactory .recoverSessionData (keyData . getAlgorithm (), keyData . getEncSessionKey () );
74+ byte [] plain = dataDecryptorFactory .recoverSessionData (keyData , encData );
7675 // symmetric cipher algorithm is stored in first octet of session data
7776 return plain [0 ];
7877 }
@@ -98,16 +97,60 @@ public PGPSessionKey getSessionKey(
9897 PublicKeyDataDecryptorFactory dataDecryptorFactory )
9998 throws PGPException
10099 {
101- byte [] sessionData = dataDecryptorFactory .recoverSessionData (keyData .getAlgorithm (), keyData .getEncSessionKey ());
102- if (keyData .getAlgorithm () == PublicKeyAlgorithmTags .X25519 || keyData .getAlgorithm () == PublicKeyAlgorithmTags .X448 )
100+ byte [] sessionInfo = dataDecryptorFactory .recoverSessionData (keyData , encData );
101+ if (containsChecksum (keyData .getAlgorithm ()))
102+ {
103+ if (!confirmCheckSum (sessionInfo ))
104+ {
105+ throw new PGPException ("Key checksum failed." );
106+ }
107+ sessionInfo = Arrays .copyOf (sessionInfo , sessionInfo .length - 2 );
108+ }
109+
110+
111+ byte [] sessionKey ;
112+ int algorithm ;
113+
114+ // OCB (LibrePGP v5 style AEAD)
115+ if (encData instanceof AEADEncDataPacket )
103116 {
104- return new PGPSessionKey (sessionData [0 ] & 0xff , Arrays .copyOfRange (sessionData , 1 , sessionData .length ));
117+ algorithm = ((AEADEncDataPacket ) encData ).getAlgorithm ();
118+ sessionKey = Arrays .copyOfRange (sessionInfo , 1 , sessionInfo .length );
105119 }
106- if (!confirmCheckSum (sessionData ))
120+
121+ // SEIPD (OpenPGP v4 / OpenPGP v6)
122+ else if (encData instanceof SymmetricEncIntegrityPacket )
107123 {
108- throw new PGPKeyValidationException ("key checksum failed" );
124+ SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket ) encData ;
125+ if (seipd .getVersion () == SymmetricEncIntegrityPacket .VERSION_1 )
126+ {
127+ algorithm = sessionInfo [0 ];
128+ sessionKey = Arrays .copyOfRange (sessionInfo , 1 , sessionInfo .length );
129+ }
130+ else if (seipd .getVersion () == SymmetricEncIntegrityPacket .VERSION_2 )
131+ {
132+ algorithm = seipd .getCipherAlgorithm ();
133+ sessionKey = Arrays .copyOfRange (sessionInfo , 1 , sessionInfo .length );
134+ }
135+ else
136+ {
137+ throw new UnsupportedPacketVersionException ("Unsupported SEIPD packet version: " + seipd .getVersion ());
138+ }
109139 }
110- return new PGPSessionKey (sessionData [0 ] & 0xff , Arrays .copyOfRange (sessionData , 1 , sessionData .length - 2 ));
140+ // SED (Legacy, no integrity protection!)
141+ else
142+ {
143+ algorithm = sessionInfo [0 ];
144+ sessionKey = Arrays .copyOfRange (sessionInfo , 1 , sessionInfo .length );
145+ }
146+
147+ return new PGPSessionKey (algorithm & 0xff , sessionKey );
148+ }
149+
150+ private boolean containsChecksum (int algorithm )
151+ {
152+ return algorithm != PublicKeyAlgorithmTags .X25519 &&
153+ algorithm != PublicKeyAlgorithmTags .X448 ;
111154 }
112155
113156 /**
@@ -169,13 +212,38 @@ private InputStream getDataStream(
169212 }
170213 else
171214 {
172- boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket ;
173215
174- PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (withIntegrityPacket , sessionKey .getAlgorithm (), sessionKey .getKey ());
216+ if (encData instanceof SymmetricEncIntegrityPacket )
217+ {
218+ SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket ) encData ;
219+ // SEIPD v1 (OpenPGP v4)
220+ if (seipd .getVersion () == SymmetricEncIntegrityPacket .VERSION_1 )
221+ {
222+ PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (true , sessionKey .getAlgorithm (), sessionKey .getKey ());
175223
176- BCPGInputStream encIn = encData .getInputStream ();
224+ BCPGInputStream encIn = encData .getInputStream ();
177225
178- processSymmetricEncIntegrityPacketDataStream (withIntegrityPacket , dataDecryptor , encIn );
226+ processSymmetricEncIntegrityPacketDataStream (true , dataDecryptor , encIn );
227+ }
228+ // SEIPD v2 (OpenPGP v6 AEAD)
229+ else
230+ {
231+ PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (seipd , sessionKey );
232+
233+ BCPGInputStream encIn = encData .getInputStream ();
234+
235+ encStream = new BCPGInputStream (dataDecryptor .getInputStream (encIn ));
236+ }
237+ }
238+ // SED (Symmetrically Encrypted Data without Integrity Protection; Deprecated)
239+ else
240+ {
241+ PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (false , sessionKey .getAlgorithm (), sessionKey .getKey ());
242+
243+ BCPGInputStream encIn = encData .getInputStream ();
244+
245+ processSymmetricEncIntegrityPacketDataStream (false , dataDecryptor , encIn );
246+ }
179247
180248 //
181249 // some versions of PGP appear to produce 0 for the extra
0 commit comments