11package org .bouncycastle .openpgp ;
22
3- import java .io .EOFException ;
43import java .io .InputStream ;
54
6- import org .bouncycastle .bcpg .AEADEncDataPacket ;
7- import org .bouncycastle .bcpg .BCPGInputStream ;
85import org .bouncycastle .bcpg .InputStreamPacket ;
9- import org .bouncycastle .bcpg .SymmetricEncIntegrityPacket ;
106import org .bouncycastle .bcpg .SymmetricKeyAlgorithmTags ;
117import org .bouncycastle .bcpg .SymmetricKeyEncSessionPacket ;
128import org .bouncycastle .openpgp .operator .PBEDataDecryptorFactory ;
13- import org .bouncycastle .openpgp .operator .PGPDataDecryptor ;
149import org .bouncycastle .openpgp .operator .SessionKeyDataDecryptorFactory ;
1510import org .bouncycastle .util .Arrays ;
16- import org .bouncycastle .util .io .TeeInputStream ;
1711
1812/**
1913 * A password based encryption object.
2317 * </p>
2418 */
2519public class PGPPBEEncryptedData
26- extends PGPEncryptedData
20+ extends PGPSymmetricEncryptedData
2721{
2822 SymmetricKeyEncSessionPacket keyData ;
2923
@@ -43,6 +37,16 @@ public class PGPPBEEncryptedData
4337 this .keyData = keyData ;
4438 }
4539
40+ public int getVersion ()
41+ {
42+ return keyData .getVersion ();
43+ }
44+
45+ public int getAlgorithm ()
46+ {
47+ return keyData .getEncAlgorithm ();
48+ }
49+
4650 /**
4751 * Return the symmetric key algorithm required to decrypt the data protected by this object.
4852 *
@@ -94,28 +98,7 @@ public InputStream getDataStream(
9498 {
9599 PGPSessionKey sessionKey = getSessionKey (dataDecryptorFactory );
96100
97- if (encData instanceof AEADEncDataPacket )
98- {
99- AEADEncDataPacket aeadData = (AEADEncDataPacket )encData ;
100-
101- if (aeadData .getAlgorithm () != sessionKey .getAlgorithm ())
102- {
103- throw new PGPException ("session key and AEAD algorithm mismatch" );
104- }
105-
106- PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (aeadData .getAEADAlgorithm (), aeadData .getIV (), aeadData .getChunkSize (), sessionKey .getAlgorithm (), sessionKey .getKey ());
107-
108- BCPGInputStream encIn = encData .getInputStream ();
109-
110- encStream = new BCPGInputStream (dataDecryptor .getInputStream (encIn ));
111- }
112- else
113- {
114- boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket ;
115- PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (withIntegrityPacket , sessionKey .getAlgorithm (), sessionKey .getKey ());
116-
117- encStream = getDataStream (withIntegrityPacket , dataDecryptor );
118- }
101+ encStream = createDecryptionStream (dataDecryptorFactory , sessionKey );
119102
120103 return encStream ;
121104 }
@@ -136,79 +119,8 @@ public InputStream getDataStream(
136119 try
137120 {
138121 PGPSessionKey sessionKey = dataDecryptorFactory .getSessionKey ();
139- boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket ;
140- PGPDataDecryptor dataDecryptor = dataDecryptorFactory .createDataDecryptor (withIntegrityPacket , sessionKey .getAlgorithm (), sessionKey .getKey ());
141-
142- return getDataStream (withIntegrityPacket , dataDecryptor );
143- }
144- catch (PGPException e )
145- {
146- throw e ;
147- }
148- catch (Exception e )
149- {
150- throw new PGPException ("Exception creating cipher" , e );
151- }
152- }
153-
154- private InputStream getDataStream (
155- boolean withIntegrityPacket ,
156- PGPDataDecryptor dataDecryptor )
157- throws PGPException
158- {
159- try
160- {
161- BCPGInputStream encIn = encData .getInputStream ();
162- encIn .mark (dataDecryptor .getBlockSize () + 2 ); // iv + 2 octets checksum
163-
164- encStream = new BCPGInputStream (dataDecryptor .getInputStream (encIn ));
165-
166- if (withIntegrityPacket )
167- {
168- truncStream = new TruncatedStream (encStream );
169-
170- integrityCalculator = dataDecryptor .getIntegrityCalculator ();
171-
172- encStream = new TeeInputStream (truncStream , integrityCalculator .getOutputStream ());
173- }
174-
175- byte [] iv = new byte [dataDecryptor .getBlockSize ()];
176- for (int i = 0 ; i != iv .length ; i ++)
177- {
178- int ch = encStream .read ();
179-
180- if (ch < 0 )
181- {
182- throw new EOFException ("unexpected end of stream." );
183- }
184-
185- iv [i ] = (byte )ch ;
186- }
187-
188- int v1 = encStream .read ();
189- int v2 = encStream .read ();
190-
191- if (v1 < 0 || v2 < 0 )
192- {
193- throw new EOFException ("unexpected end of stream." );
194- }
195-
196122
197- // Note: the oracle attack on "quick check" bytes is not deemed
198- // a security risk for PBE (see PGPPublicKeyEncryptedData)
199-
200- boolean repeatCheckPassed = iv [iv .length - 2 ] == (byte )v1
201- && iv [iv .length - 1 ] == (byte )v2 ;
202-
203- // Note: some versions of PGP appear to produce 0 for the extra
204- // bytes rather than repeating the two previous bytes
205- boolean zeroesCheckPassed = v1 == 0 && v2 == 0 ;
206-
207- if (!repeatCheckPassed && !zeroesCheckPassed )
208- {
209- encIn .reset ();
210- throw new PGPDataValidationException ("data check failed." );
211- }
123+ encStream = createDecryptionStream (dataDecryptorFactory , sessionKey );
212124
213125 return encStream ;
214126 }
@@ -221,14 +133,4 @@ private InputStream getDataStream(
221133 throw new PGPException ("Exception creating cipher" , e );
222134 }
223135 }
224-
225- public int getVersion ()
226- {
227- return keyData .getVersion ();
228- }
229-
230- public int getAlgorithm ()
231- {
232- return keyData .getEncAlgorithm ();
233- }
234136}
0 commit comments