Skip to content

Commit 1d05a25

Browse files
committed
OpenPGPKeyGenerator: Add factory methods for generating singleton- and composite RSA keys
1 parent 3adc1c5 commit 1d05a25

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKeyGenerator.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.bouncycastle.bcpg.PublicKeyUtils;
1111
import org.bouncycastle.bcpg.PublicSubkeyPacket;
1212
import org.bouncycastle.bcpg.S2K;
13+
import org.bouncycastle.bcpg.SignatureSubpacketTags;
1314
import org.bouncycastle.bcpg.sig.KeyFlags;
1415
import org.bouncycastle.openpgp.PGPException;
1516
import org.bouncycastle.openpgp.PGPKeyPair;
@@ -240,6 +241,93 @@ public PGPSignatureSubpacketGenerator apply(PGPSignatureSubpacketGenerator subpa
240241
}));
241242
}
242243

244+
/**
245+
* Generate an OpenPGP key based on a single, multipurpose RSA key of the given strength.
246+
* The key will carry a direct-key signature containing default preferences and flags.
247+
* If the passed in userId is non-null, it will be added to the key.
248+
*
249+
* @param bitStrength strength of the RSA key in bits (recommended values: 3072 and above).
250+
* @param userId optional user-id
251+
* @return builder
252+
* @throws PGPException if the key cannot be generated.
253+
*/
254+
public WithPrimaryKey singletonRSAKey(int bitStrength, String userId)
255+
throws PGPException
256+
{
257+
WithPrimaryKey builder = withPrimaryKey(
258+
new KeyPairGeneratorCallback()
259+
{
260+
@Override
261+
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
262+
throws PGPException
263+
{
264+
return generator.generateRsaKeyPair(bitStrength);
265+
}
266+
},
267+
SignatureParameters.Callback.Util.modifyHashedSubpackets(
268+
new SignatureSubpacketsFunction()
269+
{
270+
@Override
271+
public PGPSignatureSubpacketGenerator apply(PGPSignatureSubpacketGenerator subpackets)
272+
{
273+
subpackets.removePacketsOfType(SignatureSubpacketTags.KEY_FLAGS);
274+
subpackets.setKeyFlags(KeyFlags.CERTIFY_OTHER
275+
| KeyFlags.SIGN_DATA
276+
| KeyFlags.ENCRYPT_STORAGE
277+
| KeyFlags.ENCRYPT_COMMS);
278+
return subpackets;
279+
}
280+
}
281+
)
282+
);
283+
284+
if (userId != null)
285+
{
286+
builder.addUserId(userId);
287+
}
288+
289+
return builder;
290+
}
291+
292+
/**
293+
* Generate an OpenPGP key composed of 3 individual component keys based on RSA of the given strength in bits.
294+
* The primary key will be used to certify third-party keys.
295+
* A subkey is used for signing and a third subkey is used for encryption of messages both for storage and
296+
* communications.
297+
* The primary key will carry a direct-key signature containing default preferences and flags.
298+
* The subkeys will be bound with subkey binding signatures.
299+
* If the passed in userId is non-null, it will be added to the key.
300+
*
301+
* @param bitStrength strength of the keys in bits (recommended values: 3072 and above)
302+
* @param userId optional user-id
303+
* @return builder
304+
* @throws PGPException if the key cannot be generated
305+
*/
306+
public WithPrimaryKey compositeRSAKey(int bitStrength, String userId)
307+
throws PGPException
308+
{
309+
KeyPairGeneratorCallback generatorCallback = new KeyPairGeneratorCallback()
310+
{
311+
@Override
312+
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
313+
throws PGPException
314+
{
315+
return generator.generateRsaKeyPair(bitStrength);
316+
}
317+
};
318+
319+
WithPrimaryKey builder = withPrimaryKey(generatorCallback)
320+
.addSigningSubkey(generatorCallback)
321+
.addEncryptionSubkey(generatorCallback);
322+
323+
if (userId != null)
324+
{
325+
builder.addUserId(userId);
326+
}
327+
328+
return builder;
329+
}
330+
243331
/**
244332
* Generate an OpenPGP key with a certification-capable primary key.
245333
* See {@link PGPKeyPairGenerator#generatePrimaryKey()} for the primary key type

0 commit comments

Comments
 (0)