Skip to content

Commit 9b49fab

Browse files
committed
added build method taking a pre-calculated key as SecretKey and byte[] + test for same - relates to github #2115
minor refactor of Bc class.
1 parent 4919f45 commit 9b49fab

File tree

3 files changed

+109
-29
lines changed

3 files changed

+109
-29
lines changed

pkix/src/main/java/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ public OutputEncryptor build()
9595
/**
9696
* Build the OutputEncryptor using a pre-generated key.
9797
*
98-
* @param encKey a raw byte encoding of the key to be used for encryption.
99-
* @return an OutputEncryptor configured to use encKey.
98+
* @param rawEncKey a raw byte encoding of the key to be used for encryption.
99+
* @return an OutputEncryptor configured to use rawEncKey.
100100
* @throws CMSException
101101
*/
102-
public OutputEncryptor build(byte[] encKey)
102+
public OutputEncryptor build(byte[] rawEncKey)
103103
throws CMSException
104104
{
105105
if (random == null)
@@ -110,10 +110,10 @@ public OutputEncryptor build(byte[] encKey)
110110
// fixed key size defined
111111
if (this.keySize > 0)
112112
{
113-
if (((this.keySize + 7) / 8) != encKey.length)
113+
if (((this.keySize + 7) / 8) != rawEncKey.length)
114114
{
115-
if ((this.keySize != 56 && encKey.length != 8)
116-
&& (this.keySize != 168 && encKey.length != 24))
115+
if ((this.keySize != 56 && rawEncKey.length != 8)
116+
&& (this.keySize != 168 && rawEncKey.length != 24))
117117
{
118118
throw new IllegalArgumentException("attempt to create encryptor with the wrong sized key");
119119
}
@@ -122,10 +122,10 @@ public OutputEncryptor build(byte[] encKey)
122122

123123
if (helper.isAuthEnveloped(encryptionOID))
124124
{
125-
return new CMSAuthOutputEncryptor(encryptionOID, new KeyParameter(encKey), random);
125+
return new CMSAuthOutputEncryptor(encryptionOID, new KeyParameter(rawEncKey), random);
126126
}
127127

128-
return new CMSOutputEncryptor(encryptionOID, new KeyParameter(encKey), random);
128+
return new CMSOutputEncryptor(encryptionOID, new KeyParameter(rawEncKey), random);
129129
}
130130

131131
private class CMSOutputEncryptor

pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,63 @@ public JceCMSContentEncryptorBuilder setAlgorithmParameters(AlgorithmParameters
181181
return this;
182182
}
183183

184+
/**
185+
* Build the OutputEncryptor with an internally generated key.
186+
*
187+
* @return an OutputEncryptor configured to use an internal key.
188+
* @throws CMSException
189+
*/
184190
public OutputEncryptor build()
185191
throws CMSException
192+
{
193+
KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID);
194+
195+
random = CryptoServicesRegistrar.getSecureRandom(random);
196+
197+
if (keySize < 0)
198+
{
199+
keyGen.init(random);
200+
}
201+
else
202+
{
203+
keyGen.init(keySize, random);
204+
}
205+
206+
return build(keyGen.generateKey());
207+
}
208+
209+
/**
210+
* Build the OutputEncryptor using a pre-generated key given as a raw encoding.
211+
*
212+
* @param rawEncKey a raw byte encoding of the key to be used for encryption.
213+
* @return an OutputEncryptor configured to use rawEncKey.
214+
* @throws CMSException
215+
*/
216+
public OutputEncryptor build(byte[] rawEncKey)
217+
throws CMSException
218+
{
219+
SecretKey encKey = new SecretKeySpec(rawEncKey, helper.getBaseCipherName(encryptionOID));
220+
221+
return build(encKey);
222+
}
223+
224+
/**
225+
* Build the OutputEncryptor using a pre-generated key.
226+
*
227+
* @param encKey a pre-generated key to be used for encryption.
228+
* @return an OutputEncryptor configured to use encKey.
229+
* @throws CMSException
230+
*/
231+
public OutputEncryptor build(SecretKey encKey)
232+
throws CMSException
186233
{
187234
if (algorithmParameters != null)
188235
{
189236
if (helper.isAuthEnveloped(encryptionOID))
190237
{
191-
return new CMSAuthOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random);
238+
return new CMSAuthOutputEncryptor(kdfAlgorithm, encryptionOID, encKey, algorithmParameters, random);
192239
}
193-
return new CMSOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random);
240+
return new CMSOutputEncryptor(kdfAlgorithm, encryptionOID, encKey, algorithmParameters, random);
194241
}
195242
if (algorithmIdentifier != null)
196243
{
@@ -212,9 +259,9 @@ public OutputEncryptor build()
212259

213260
if (helper.isAuthEnveloped(encryptionOID))
214261
{
215-
return new CMSAuthOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random);
262+
return new CMSAuthOutputEncryptor(kdfAlgorithm, encryptionOID, encKey, algorithmParameters, random);
216263
}
217-
return new CMSOutputEncryptor(kdfAlgorithm, encryptionOID, keySize, algorithmParameters, random);
264+
return new CMSOutputEncryptor(kdfAlgorithm, encryptionOID, encKey, algorithmParameters, random);
218265
}
219266

220267
private class CMSOutEncryptor
@@ -252,24 +299,14 @@ private void applyKdf(ASN1ObjectIdentifier kdfAlgorithm, AlgorithmParameters par
252299
algorithmIdentifier = new AlgorithmIdentifier(kdfAlgorithm, algorithmIdentifier);
253300
}
254301

255-
protected void init(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random)
302+
protected void init(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, SecretKey encKey, AlgorithmParameters params, SecureRandom random)
256303
throws CMSException
257304
{
258-
KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID);
305+
this.encKey = encKey;
259306

260307
random = CryptoServicesRegistrar.getSecureRandom(random);
261308

262-
if (keySize < 0)
263-
{
264-
keyGen.init(random);
265-
}
266-
else
267-
{
268-
keyGen.init(keySize, random);
269-
}
270-
271-
cipher = helper.createCipher(encryptionOID);
272-
encKey = keyGen.generateKey();
309+
this.cipher = helper.createCipher(encryptionOID);
273310

274311
if (params == null)
275312
{
@@ -327,10 +364,10 @@ private class CMSOutputEncryptor
327364
extends CMSOutEncryptor
328365
implements OutputEncryptor
329366
{
330-
CMSOutputEncryptor(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random)
367+
CMSOutputEncryptor(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, SecretKey encKey, AlgorithmParameters params, SecureRandom random)
331368
throws CMSException
332369
{
333-
init(kdfAlgorithm, encryptionOID, keySize, params, random);
370+
init(kdfAlgorithm, encryptionOID, encKey, params, random);
334371
}
335372

336373
public AlgorithmIdentifier getAlgorithmIdentifier()
@@ -355,10 +392,10 @@ private class CMSAuthOutputEncryptor
355392
{
356393
private MacCaptureStream macOut;
357394

358-
CMSAuthOutputEncryptor(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random)
395+
CMSAuthOutputEncryptor(ASN1ObjectIdentifier kdfAlgorithm, ASN1ObjectIdentifier encryptionOID, SecretKey encKey, AlgorithmParameters params, SecureRandom random)
359396
throws CMSException
360397
{
361-
init(kdfAlgorithm, encryptionOID, keySize, params, random);
398+
init(kdfAlgorithm, encryptionOID, encKey, params, random);
362399
}
363400

364401
public AlgorithmIdentifier getAlgorithmIdentifier()

pkix/src/test/java/org/bouncycastle/cms/test/NewEnvelopedDataStreamTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,49 @@ public void testTwoAESKEK()
775775
ep.close();
776776
}
777777

778+
public void testTwoAESKEKWithPrecomputedContentKey()
779+
throws Exception
780+
{
781+
byte[] data = "WallaWallaWashington".getBytes();
782+
SecretKey kek1 = CMSTestUtil.makeAES192Key();
783+
SecretKey kek2 = CMSTestUtil.makeAES192Key();
784+
785+
CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator();
786+
787+
byte[] kekId1 = new byte[]{1, 2, 3, 4, 5};
788+
byte[] kekId2 = new byte[]{5, 4, 3, 2, 1};
789+
790+
edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId1, kek1).setProvider(BC));
791+
edGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId2, kek2).setProvider(BC));
792+
793+
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
794+
795+
OutputStream out = edGen.open(
796+
bOut,
797+
new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build(Hex.decode("000102030405060708090a0b0c0d0e0f")));
798+
out.write(data);
799+
800+
out.close();
801+
802+
CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bOut.toByteArray());
803+
804+
RecipientInformationStore recipients = ep.getRecipientInfos();
805+
806+
assertEquals(ep.getEncryptionAlgOID(), CMSEnvelopedDataGenerator.AES128_CBC);
807+
808+
RecipientId recSel = new KEKRecipientId(kekId2);
809+
810+
RecipientInformation recipient = recipients.get(recSel);
811+
812+
assertEquals(recipient.getKeyEncryptionAlgOID(), "2.16.840.1.101.3.4.1.25");
813+
814+
CMSTypedStream recData = recipient.getContentStream(new JceKEKEnvelopedRecipient(kek2).setProvider(BC));
815+
816+
assertEquals(true, Arrays.equals(data, CMSTestUtil.streamToByteArray(recData.getContentStream())));
817+
818+
ep.close();
819+
}
820+
778821
public void testECKeyAgree()
779822
throws Exception
780823
{

0 commit comments

Comments
 (0)