mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 12:52:07 +01:00
Further simplify the KeyRingBuilder API
This commit is contained in:
parent
387b2b4b43
commit
be47a96030
15 changed files with 316 additions and 400 deletions
|
@ -61,14 +61,18 @@ import org.pgpainless.provider.ProviderFactory;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil;
|
import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil;
|
||||||
|
|
||||||
public class KeyRingBuilder implements KeyRingBuilderInterface {
|
public class KeyRingBuilder implements KeyRingBuilderInterface<KeyRingBuilder> {
|
||||||
|
|
||||||
private final Charset UTF8 = Charset.forName("UTF-8");
|
private final Charset UTF8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
private final List<KeySpec> keySpecs = new ArrayList<>();
|
private PGPSignatureGenerator signatureGenerator;
|
||||||
private String userId;
|
private PGPDigestCalculator digestCalculator;
|
||||||
private final Set<String> additionalUserIds = new LinkedHashSet<>();
|
private PBESecretKeyEncryptor secretKeyEncryptor;
|
||||||
private Passphrase passphrase;
|
|
||||||
|
private KeySpec primaryKeySpec;
|
||||||
|
private final List<KeySpec> subkeySpecs = new ArrayList<>();
|
||||||
|
private final Set<String> userIds = new LinkedHashSet<>();
|
||||||
|
private Passphrase passphrase = null;
|
||||||
private Date expirationDate = null;
|
private Date expirationDate = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,17 +130,14 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
*/
|
*/
|
||||||
public PGPSecretKeyRing simpleRsaKeyRing(@Nonnull String userId, @Nonnull RsaLength length, String password)
|
public PGPSecretKeyRing simpleRsaKeyRing(@Nonnull String userId, @Nonnull RsaLength length, String password)
|
||||||
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||||
WithAdditionalUserIdOrPassphrase builder = this
|
KeyRingBuilder builder = new KeyRingBuilder()
|
||||||
.withPrimaryKey(KeySpec
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.RSA(length), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.ENCRYPT_COMMS))
|
||||||
.getBuilder(KeyType.RSA(length), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.ENCRYPT_COMMS)
|
.addUserId(userId);
|
||||||
.build())
|
|
||||||
.withPrimaryUserId(userId);
|
|
||||||
|
|
||||||
if (password == null) {
|
if (!isNullOrEmpty(password)) {
|
||||||
return builder.withoutPassphrase().build();
|
builder.setPassphrase(Passphrase.fromPassword(password));
|
||||||
} else {
|
|
||||||
return builder.withPassphrase(new Passphrase(password.toCharArray())).build();
|
|
||||||
}
|
}
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,20 +195,15 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
*/
|
*/
|
||||||
public PGPSecretKeyRing simpleEcKeyRing(@Nonnull String userId, String password)
|
public PGPSecretKeyRing simpleEcKeyRing(@Nonnull String userId, String password)
|
||||||
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||||
WithAdditionalUserIdOrPassphrase builder = this
|
KeyRingBuilder builder = new KeyRingBuilder()
|
||||||
.withSubKey(
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS))
|
||||||
.build())
|
.addUserId(userId);
|
||||||
.withPrimaryKey(
|
|
||||||
KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
|
||||||
.build())
|
|
||||||
.withPrimaryUserId(userId);
|
|
||||||
|
|
||||||
if (password == null) {
|
if (!isNullOrEmpty(password)) {
|
||||||
return builder.withoutPassphrase().build();
|
builder.setPassphrase(Passphrase.fromPassword(password));
|
||||||
} else {
|
|
||||||
return builder.withPassphrase(new Passphrase(password.toCharArray())).build();
|
|
||||||
}
|
}
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -220,37 +216,59 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
*/
|
*/
|
||||||
public PGPSecretKeyRing modernKeyRing(String userId, String password)
|
public PGPSecretKeyRing modernKeyRing(String userId, String password)
|
||||||
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
|
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
|
||||||
WithAdditionalUserIdOrPassphrase builder = this
|
KeyRingBuilder builder = new KeyRingBuilder()
|
||||||
.withSubKey(
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER))
|
||||||
KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS))
|
||||||
.build())
|
.addSubkey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.SIGN_DATA))
|
||||||
.withSubKey(
|
.addUserId(userId);
|
||||||
KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.SIGN_DATA)
|
if (!isNullOrEmpty(password)) {
|
||||||
.build())
|
builder.setPassphrase(Passphrase.fromPassword(password));
|
||||||
.withPrimaryKey(
|
|
||||||
KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER)
|
|
||||||
.build())
|
|
||||||
.withPrimaryUserId(userId);
|
|
||||||
|
|
||||||
if (password == null) {
|
|
||||||
return builder.withoutPassphrase().build();
|
|
||||||
} else {
|
|
||||||
return builder.withPassphrase(new Passphrase(password.toCharArray())).build();
|
|
||||||
}
|
}
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyRingBuilderInterface withSubKey(@Nonnull KeySpec type) {
|
public KeyRingBuilder setPrimaryKey(@Nonnull KeySpec keySpec) {
|
||||||
KeyRingBuilder.this.keySpecs.add(type);
|
verifyMasterKeyCanCertify(keySpec);
|
||||||
|
this.primaryKeySpec = keySpec;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WithPrimaryUserId withPrimaryKey(@Nonnull KeySpec spec) {
|
public KeyRingBuilder addSubkey(@Nonnull KeySpec keySpec) {
|
||||||
verifyMasterKeyCanCertify(spec);
|
this.subkeySpecs.add(keySpec);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
KeyRingBuilder.this.keySpecs.add(0, spec);
|
@Override
|
||||||
return new WithPrimaryUserIdImpl();
|
public KeyRingBuilder addUserId(@Nonnull String userId) {
|
||||||
|
this.userIds.add(userId.trim());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyRingBuilder addUserId(@Nonnull byte[] userId) {
|
||||||
|
return addUserId(new String(userId, UTF8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyRingBuilder setExpirationDate(@Nonnull Date expirationDate) {
|
||||||
|
Date now = new Date();
|
||||||
|
if (now.after(expirationDate)) {
|
||||||
|
throw new IllegalArgumentException("Expiration date must be in the future.");
|
||||||
|
}
|
||||||
|
this.expirationDate = expirationDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyRingBuilder setPassphrase(@Nonnull Passphrase passphrase) {
|
||||||
|
this.passphrase = passphrase;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isNullOrEmpty(String password) {
|
||||||
|
return password == null || password.trim().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyMasterKeyCanCertify(KeySpec spec) {
|
private void verifyMasterKeyCanCertify(KeySpec spec) {
|
||||||
|
@ -270,68 +288,12 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
return keySpec.getKeyType().canCertify();
|
return keySpec.getKeyType().canCertify();
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithPrimaryUserIdImpl implements WithPrimaryUserId {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WithAdditionalUserIdOrPassphrase withPrimaryUserId(@Nonnull String userId) {
|
|
||||||
KeyRingBuilder.this.userId = userId.trim();
|
|
||||||
return new WithAdditionalUserIdOrPassphraseImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WithAdditionalUserIdOrPassphrase withPrimaryUserId(@Nonnull byte[] userId) {
|
|
||||||
return withPrimaryUserId(new String(userId, UTF8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WithAdditionalUserIdOrPassphraseImpl implements WithAdditionalUserIdOrPassphrase {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WithAdditionalUserIdOrPassphrase setExpirationDate(@Nonnull Date expirationDate) {
|
|
||||||
Date now = new Date();
|
|
||||||
if (now.after(expirationDate)) {
|
|
||||||
throw new IllegalArgumentException("Expiration date must be in the future.");
|
|
||||||
}
|
|
||||||
KeyRingBuilder.this.expirationDate = expirationDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WithAdditionalUserIdOrPassphrase withAdditionalUserId(@Nonnull String userId) {
|
|
||||||
String trimmed = userId.trim();
|
|
||||||
if (KeyRingBuilder.this.userId.equals(trimmed)) {
|
|
||||||
throw new IllegalArgumentException("Additional user-id MUST NOT be equal to primary user-id.");
|
|
||||||
}
|
|
||||||
KeyRingBuilder.this.additionalUserIds.add(trimmed);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WithAdditionalUserIdOrPassphrase withAdditionalUserId(@Nonnull byte[] userId) {
|
|
||||||
return withAdditionalUserId(new String(userId, UTF8));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Build withPassphrase(@Nonnull Passphrase passphrase) {
|
|
||||||
KeyRingBuilder.this.passphrase = passphrase;
|
|
||||||
return new BuildImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Build withoutPassphrase() {
|
|
||||||
KeyRingBuilder.this.passphrase = null;
|
|
||||||
return new BuildImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
class BuildImpl implements Build {
|
|
||||||
|
|
||||||
private PGPSignatureGenerator signatureGenerator;
|
|
||||||
private PGPDigestCalculator digestCalculator;
|
|
||||||
private PBESecretKeyEncryptor secretKeyEncryptor;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException,
|
public PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException,
|
||||||
InvalidAlgorithmParameterException {
|
InvalidAlgorithmParameterException {
|
||||||
|
if (userIds.isEmpty()) {
|
||||||
|
throw new IllegalStateException("At least one user-id is required.");
|
||||||
|
}
|
||||||
digestCalculator = buildDigestCalculator();
|
digestCalculator = buildDigestCalculator();
|
||||||
secretKeyEncryptor = buildSecretKeyEncryptor();
|
secretKeyEncryptor = buildSecretKeyEncryptor();
|
||||||
PBESecretKeyDecryptor secretKeyDecryptor = buildSecretKeyDecryptor();
|
PBESecretKeyDecryptor secretKeyDecryptor = buildSecretKeyDecryptor();
|
||||||
|
@ -340,14 +302,11 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
passphrase.clear();
|
passphrase.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// First key is the Master Key
|
// Generate Primary Key
|
||||||
KeySpec certKeySpec = keySpecs.remove(0);
|
PGPKeyPair certKey = generateKeyPair(primaryKeySpec);
|
||||||
|
|
||||||
// Generate Master Key
|
|
||||||
PGPKeyPair certKey = generateKeyPair(certKeySpec);
|
|
||||||
PGPContentSignerBuilder signer = buildContentSigner(certKey);
|
PGPContentSignerBuilder signer = buildContentSigner(certKey);
|
||||||
signatureGenerator = new PGPSignatureGenerator(signer);
|
signatureGenerator = new PGPSignatureGenerator(signer);
|
||||||
PGPSignatureSubpacketGenerator hashedSubPacketGenerator = certKeySpec.getSubpacketGenerator();
|
PGPSignatureSubpacketGenerator hashedSubPacketGenerator = primaryKeySpec.getSubpacketGenerator();
|
||||||
hashedSubPacketGenerator.setPrimaryUserID(false, true);
|
hashedSubPacketGenerator.setPrimaryUserID(false, true);
|
||||||
if (expirationDate != null) {
|
if (expirationDate != null) {
|
||||||
SignatureSubpacketGeneratorUtil.setExpirationDateInSubpacketGenerator(
|
SignatureSubpacketGeneratorUtil.setExpirationDateInSubpacketGenerator(
|
||||||
|
@ -368,7 +327,10 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
// Attempt to add additional user-ids to the primary public key
|
// Attempt to add additional user-ids to the primary public key
|
||||||
PGPPublicKey primaryPubKey = secretKeys.next().getPublicKey();
|
PGPPublicKey primaryPubKey = secretKeys.next().getPublicKey();
|
||||||
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKeyRing.getSecretKey(), secretKeyDecryptor);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKeyRing.getSecretKey(), secretKeyDecryptor);
|
||||||
for (String additionalUserId : additionalUserIds) {
|
Iterator<String> additionalUserIds = userIds.iterator();
|
||||||
|
additionalUserIds.next(); // Skip primary user id
|
||||||
|
while (additionalUserIds.hasNext()) {
|
||||||
|
String additionalUserId = additionalUserIds.next();
|
||||||
signatureGenerator.init(SignatureType.POSITIVE_CERTIFICATION.getCode(), privateKey);
|
signatureGenerator.init(SignatureType.POSITIVE_CERTIFICATION.getCode(), privateKey);
|
||||||
PGPSignature additionalUserIdSignature =
|
PGPSignature additionalUserIdSignature =
|
||||||
signatureGenerator.generateCertification(additionalUserId, primaryPubKey);
|
signatureGenerator.generateCertification(additionalUserId, primaryPubKey);
|
||||||
|
@ -394,15 +356,16 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
PGPContentSignerBuilder signer,
|
PGPContentSignerBuilder signer,
|
||||||
PGPSignatureSubpacketVector hashedSubPackets)
|
PGPSignatureSubpacketVector hashedSubPackets)
|
||||||
throws PGPException {
|
throws PGPException {
|
||||||
|
String primaryUserId = userIds.iterator().next();
|
||||||
return new PGPKeyRingGenerator(
|
return new PGPKeyRingGenerator(
|
||||||
SignatureType.POSITIVE_CERTIFICATION.getCode(), certKey,
|
SignatureType.POSITIVE_CERTIFICATION.getCode(), certKey,
|
||||||
userId, digestCalculator,
|
primaryUserId, digestCalculator,
|
||||||
hashedSubPackets, null, signer, secretKeyEncryptor);
|
hashedSubPackets, null, signer, secretKeyEncryptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSubKeys(PGPKeyPair primaryKey, PGPKeyRingGenerator ringGenerator)
|
private void addSubKeys(PGPKeyPair primaryKey, PGPKeyRingGenerator ringGenerator)
|
||||||
throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException {
|
throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException {
|
||||||
for (KeySpec subKeySpec : keySpecs) {
|
for (KeySpec subKeySpec : subkeySpecs) {
|
||||||
PGPKeyPair subKey = generateKeyPair(subKeySpec);
|
PGPKeyPair subKey = generateKeyPair(subKeySpec);
|
||||||
if (subKeySpec.isInheritedSubPackets()) {
|
if (subKeySpec.isInheritedSubPackets()) {
|
||||||
ringGenerator.addSubKey(subKey);
|
ringGenerator.addSubKey(subKey);
|
||||||
|
@ -459,8 +422,6 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
private PGPDigestCalculator buildDigestCalculator() throws PGPException {
|
private PGPDigestCalculator buildDigestCalculator() throws PGPException {
|
||||||
return ImplementationFactory.getInstance().getPGPDigestCalculator(HashAlgorithm.SHA1);
|
return ImplementationFactory.getInstance().getPGPDigestCalculator(HashAlgorithm.SHA1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PGPKeyPair generateKeyPair(KeySpec spec)
|
public static PGPKeyPair generateKeyPair(KeySpec spec)
|
||||||
throws NoSuchAlgorithmException, PGPException,
|
throws NoSuchAlgorithmException, PGPException,
|
||||||
|
|
|
@ -25,50 +25,32 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.pgpainless.key.util.UserId;
|
import org.pgpainless.key.util.UserId;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
public interface KeyRingBuilderInterface {
|
public interface KeyRingBuilderInterface<B extends KeyRingBuilderInterface<B>> {
|
||||||
|
|
||||||
KeyRingBuilderInterface withSubKey(@Nonnull KeySpec keySpec);
|
B setPrimaryKey(@Nonnull KeySpec keySpec);
|
||||||
|
|
||||||
WithPrimaryUserId withPrimaryKey(@Nonnull KeySpec keySpec);
|
default B setPrimaryKey(@Nonnull KeySpecBuilder builder) {
|
||||||
|
return setPrimaryKey(builder.build());
|
||||||
interface WithPrimaryUserId {
|
|
||||||
|
|
||||||
default WithAdditionalUserIdOrPassphrase withPrimaryUserId(@Nonnull UserId userId) {
|
|
||||||
return withPrimaryUserId(userId.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WithAdditionalUserIdOrPassphrase withPrimaryUserId(@Nonnull String userId);
|
B addSubkey(@Nonnull KeySpec keySpec);
|
||||||
|
|
||||||
WithAdditionalUserIdOrPassphrase withPrimaryUserId(@Nonnull byte[] userId);
|
|
||||||
|
|
||||||
|
default B addSubkey(@Nonnull KeySpecBuilder builder) {
|
||||||
|
return addSubkey(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WithAdditionalUserIdOrPassphrase {
|
default B addUserId(UserId userId) {
|
||||||
|
return addUserId(userId.toString());
|
||||||
default WithAdditionalUserIdOrPassphrase withAdditionalUserId(@Nonnull UserId userId) {
|
|
||||||
return withAdditionalUserId(userId.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
B addUserId(@Nonnull String userId);
|
||||||
* Set an expiration date for the key.
|
|
||||||
*
|
|
||||||
* @param expirationDate date on which the key will expire.
|
|
||||||
* @return builder
|
|
||||||
*/
|
|
||||||
WithAdditionalUserIdOrPassphrase setExpirationDate(@Nonnull Date expirationDate);
|
|
||||||
|
|
||||||
WithAdditionalUserIdOrPassphrase withAdditionalUserId(@Nonnull String userId);
|
B addUserId(@Nonnull byte[] userId);
|
||||||
|
|
||||||
WithAdditionalUserIdOrPassphrase withAdditionalUserId(@Nonnull byte[] userId);
|
B setExpirationDate(@Nonnull Date expirationDate);
|
||||||
|
|
||||||
Build withPassphrase(@Nonnull Passphrase passphrase);
|
B setPassphrase(@Nonnull Passphrase passphrase);
|
||||||
|
|
||||||
Build withoutPassphrase();
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Build {
|
|
||||||
|
|
||||||
PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException,
|
PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException,
|
||||||
InvalidAlgorithmParameterException;
|
InvalidAlgorithmParameterException;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,14 +88,13 @@ public class EncryptDecryptTest {
|
||||||
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
||||||
PGPSecretKeyRing sender = PGPainless.generateKeyRing().simpleRsaKeyRing("romeo@montague.lit", RsaLength._3072);
|
PGPSecretKeyRing sender = PGPainless.generateKeyRing().simpleRsaKeyRing("romeo@montague.lit", RsaLength._3072);
|
||||||
PGPSecretKeyRing recipient = PGPainless.generateKeyRing()
|
PGPSecretKeyRing recipient = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
ElGamal.withLength(ElGamalLength._3072),
|
|
||||||
KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
|
|
||||||
.build())
|
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
|
||||||
KeyType.RSA(RsaLength._4096),
|
KeyType.RSA(RsaLength._4096),
|
||||||
KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER).build())
|
KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER))
|
||||||
.withPrimaryUserId("juliet@capulet.lit").withoutPassphrase().build();
|
.addSubkey(KeySpec.getBuilder(
|
||||||
|
ElGamal.withLength(ElGamalLength._3072),
|
||||||
|
KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS))
|
||||||
|
.addUserId("juliet@capulet.lit").build();
|
||||||
|
|
||||||
encryptDecryptForSecretKeyRings(sender, recipient);
|
encryptDecryptForSecretKeyRings(sender, recipient);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,14 +59,13 @@ public class EncryptionOptionsTest {
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void generateKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
public static void generateKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||||
secretKeys = PGPainless.generateKeyRing()
|
secretKeys = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS)
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER)
|
||||||
.build())
|
.build())
|
||||||
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_STORAGE)
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS)
|
||||||
.build())
|
.build())
|
||||||
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER)
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_STORAGE)
|
||||||
.build())
|
.build())
|
||||||
.withPrimaryUserId("test@pgpainless.org")
|
.addUserId("test@pgpainless.org")
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
||||||
|
@ -139,10 +138,9 @@ public class EncryptionOptionsTest {
|
||||||
public void testAddRecipient_KeyWithoutEncryptionKeyFails() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
public void testAddRecipient_KeyWithoutEncryptionKeyFails() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||||
EncryptionOptions options = new EncryptionOptions();
|
EncryptionOptions options = new EncryptionOptions();
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.build())
|
.addUserId("test@pgpainless.org")
|
||||||
.withPrimaryUserId("test@pgpainless.org")
|
.build();
|
||||||
.withoutPassphrase().build();
|
|
||||||
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
||||||
|
|
||||||
assertThrows(IllegalArgumentException.class, () -> options.addRecipient(publicKeys));
|
assertThrows(IllegalArgumentException.class, () -> options.addRecipient(publicKeys));
|
||||||
|
|
|
@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
@ -34,6 +35,7 @@ import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.key.generation.KeySpec;
|
import org.pgpainless.key.generation.KeySpec;
|
||||||
|
import org.pgpainless.key.generation.KeySpecBuilder;
|
||||||
import org.pgpainless.key.generation.type.KeyType;
|
import org.pgpainless.key.generation.type.KeyType;
|
||||||
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
|
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
|
||||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
||||||
|
@ -156,10 +158,11 @@ public class GenerateKeys {
|
||||||
* algorithm preferences.
|
* algorithm preferences.
|
||||||
*
|
*
|
||||||
* If the target key amalgamation (key ring) should consist of more than just a single (sub-)key, start by providing
|
* If the target key amalgamation (key ring) should consist of more than just a single (sub-)key, start by providing
|
||||||
* the specifications for the subkeys first (in {@link org.pgpainless.key.generation.KeyRingBuilderInterface#withSubKey(KeySpec)})
|
* the primary key specification using {@link org.pgpainless.key.generation.KeyRingBuilder#setPrimaryKey(KeySpec)}.
|
||||||
* and add the primary key specification last (in {@link org.pgpainless.key.generation.KeyRingBuilderInterface#withPrimaryKey(KeySpec)}.
|
* Any additional subkeys can be then added using {@link org.pgpainless.key.generation.KeyRingBuilder#addSubkey(KeySpec)}.
|
||||||
*
|
*
|
||||||
* {@link KeySpec} objects can best be obtained by using the {@link KeySpec#getBuilder(KeyType, KeyFlag...)} method and providing a {@link KeyType}.
|
* {@link KeySpec} objects can best be obtained by using the {@link KeySpec#getBuilder(KeyType, KeyFlag, KeyFlag...)}
|
||||||
|
* method and providing a {@link KeyType}.
|
||||||
* There are a bunch of factory methods for different {@link KeyType} implementations present in {@link KeyType} itself
|
* There are a bunch of factory methods for different {@link KeyType} implementations present in {@link KeyType} itself
|
||||||
* (such as {@link KeyType#ECDH(EllipticCurve)}. {@link KeyFlag KeyFlags} determine
|
* (such as {@link KeyType#ECDH(EllipticCurve)}. {@link KeyFlag KeyFlags} determine
|
||||||
* the use of the key, like encryption, signing data or certifying subkeys.
|
* the use of the key, like encryption, signing data or certifying subkeys.
|
||||||
|
@ -171,16 +174,18 @@ public class GenerateKeys {
|
||||||
*
|
*
|
||||||
* Note, that if you set preferred algorithms, the preference lists are sorted from high priority to low priority.
|
* Note, that if you set preferred algorithms, the preference lists are sorted from high priority to low priority.
|
||||||
*
|
*
|
||||||
* When setting the primary key spec ({@link org.pgpainless.key.generation.KeyRingBuilder#withPrimaryKey(KeySpec)}),
|
* When setting the primary key spec ({@link org.pgpainless.key.generation.KeyRingBuilder#setPrimaryKey(KeySpecBuilder)}),
|
||||||
* make sure that the primary key spec has the {@link KeyFlag} {@link KeyFlag#CERTIFY_OTHER} set, as this is a requirement
|
* make sure that the primary key spec has the {@link KeyFlag} {@link KeyFlag#CERTIFY_OTHER} set, as this is a requirement
|
||||||
* for primary keys.
|
* for primary keys.
|
||||||
*
|
*
|
||||||
* Furthermore you have to set at least the primary user-id via
|
* Furthermore you have to set at least the primary user-id via
|
||||||
* {@link org.pgpainless.key.generation.KeyRingBuilderInterface.WithPrimaryUserId#withPrimaryUserId(String)},
|
* {@link org.pgpainless.key.generation.KeyRingBuilder#addUserId(String)},
|
||||||
* but you can also add additional user-ids via
|
* but you can also add additional user-ids.
|
||||||
* {@link org.pgpainless.key.generation.KeyRingBuilderInterface.WithAdditionalUserIdOrPassphrase#withAdditionalUserId(String)}.
|
|
||||||
*
|
*
|
||||||
* Lastly you can decide whether to set a passphrase to protect the secret key.
|
* If you want the key to expire at a certain point in time, call
|
||||||
|
* {@link org.pgpainless.key.generation.KeyRingBuilder#setExpirationDate(Date)}.
|
||||||
|
* Lastly you can decide whether to set a passphrase to protect the secret key using
|
||||||
|
* {@link org.pgpainless.key.generation.KeyRingBuilder#setPassphrase(Passphrase)}.
|
||||||
*
|
*
|
||||||
* @throws PGPException
|
* @throws PGPException
|
||||||
* @throws InvalidAlgorithmParameterException
|
* @throws InvalidAlgorithmParameterException
|
||||||
|
@ -201,9 +206,11 @@ public class GenerateKeys {
|
||||||
Passphrase passphrase = Passphrase.fromPassword("1nters3x");
|
Passphrase passphrase = Passphrase.fromPassword("1nters3x");
|
||||||
|
|
||||||
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
||||||
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||||
|
// The primary key MUST carry the CERTIFY_OTHER flag, but CAN carry additional flags
|
||||||
|
KeyFlag.CERTIFY_OTHER))
|
||||||
// Add the first subkey (in this case encryption)
|
// Add the first subkey (in this case encryption)
|
||||||
.withSubKey(
|
.addSubkey(KeySpec.getBuilder(
|
||||||
KeySpec.getBuilder(
|
|
||||||
// We choose an ECDH key over the brainpoolp256r1 curve
|
// We choose an ECDH key over the brainpoolp256r1 curve
|
||||||
KeyType.ECDH(EllipticCurve._BRAINPOOLP256R1),
|
KeyType.ECDH(EllipticCurve._BRAINPOOLP256R1),
|
||||||
// Our key can encrypt both communication data, as well as data at rest
|
// Our key can encrypt both communication data, as well as data at rest
|
||||||
|
@ -215,29 +222,19 @@ public class GenerateKeys {
|
||||||
.overridePreferredSymmetricKeyAlgorithms(SymmetricKeyAlgorithm.AES_256, SymmetricKeyAlgorithm.AES_192, SymmetricKeyAlgorithm.AES_128)
|
.overridePreferredSymmetricKeyAlgorithms(SymmetricKeyAlgorithm.AES_256, SymmetricKeyAlgorithm.AES_192, SymmetricKeyAlgorithm.AES_128)
|
||||||
.overridePreferredHashAlgorithms(HashAlgorithm.SHA512, HashAlgorithm.SHA384, HashAlgorithm.SHA256)
|
.overridePreferredHashAlgorithms(HashAlgorithm.SHA512, HashAlgorithm.SHA384, HashAlgorithm.SHA256)
|
||||||
.overridePreferredCompressionAlgorithms(CompressionAlgorithm.ZIP, CompressionAlgorithm.BZIP2, CompressionAlgorithm.ZLIB)
|
.overridePreferredCompressionAlgorithms(CompressionAlgorithm.ZIP, CompressionAlgorithm.BZIP2, CompressionAlgorithm.ZLIB)
|
||||||
.build()
|
.build())
|
||||||
)
|
|
||||||
// Add the second subkey (signing)
|
// Add the second subkey (signing)
|
||||||
.withSubKey(
|
.addSubkey(KeySpec.getBuilder(
|
||||||
KeySpec.getBuilder(
|
|
||||||
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1),
|
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1),
|
||||||
// This key is used for creating signatures only
|
// This key is used for creating signatures only
|
||||||
KeyFlag.SIGN_DATA
|
KeyFlag.SIGN_DATA
|
||||||
).build()
|
))
|
||||||
)
|
|
||||||
// Lastly we add the primary key (certification only in our case)
|
|
||||||
.withPrimaryKey(
|
|
||||||
KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519),
|
|
||||||
// The primary key MUST carry the CERTIFY_OTHER flag, but CAN carry additional flags
|
|
||||||
KeyFlag.CERTIFY_OTHER)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
// Set primary user-id
|
// Set primary user-id
|
||||||
.withPrimaryUserId(userId)
|
.addUserId(userId)
|
||||||
// Add an additional user id. This step can be repeated
|
// Add an additional user id. This step can be repeated
|
||||||
.withAdditionalUserId(additionalUserId)
|
.addUserId(additionalUserId)
|
||||||
// Set passphrase. Alternatively use .withoutPassphrase() to leave key unprotected.
|
// Set passphrase. Alternatively use .withoutPassphrase() to leave key unprotected.
|
||||||
.withPassphrase(passphrase)
|
.setPassphrase(passphrase)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -83,17 +83,15 @@ public class BrainpoolKeyGenerationTest {
|
||||||
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
||||||
|
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.SIGN_DATA).build())
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
.withSubKey(KeySpec.getBuilder(
|
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1), KeyFlag.CERTIFY_OTHER))
|
||||||
KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
|
.addSubkey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.SIGN_DATA))
|
||||||
.build())
|
.addSubkey(KeySpec.getBuilder(
|
||||||
.withSubKey(KeySpec.getBuilder(
|
KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE))
|
||||||
KeyType.RSA(RsaLength._3072), KeyFlag.SIGN_DATA)
|
.addSubkey(KeySpec.getBuilder(
|
||||||
.build())
|
KeyType.RSA(RsaLength._3072), KeyFlag.SIGN_DATA))
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
.addUserId(UserId.nameAndEmail("Alice", "alice@pgpainless.org"))
|
||||||
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1), KeyFlag.CERTIFY_OTHER).build())
|
.setPassphrase(Passphrase.fromPassword("passphrase"))
|
||||||
.withPrimaryUserId(UserId.nameAndEmail("Alice", "alice@pgpainless.org"))
|
|
||||||
.withPassphrase(Passphrase.fromPassword("passphrase"))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
for (PGPSecretKey key : secretKeys) {
|
for (PGPSecretKey key : secretKeys) {
|
||||||
|
@ -131,10 +129,9 @@ public class BrainpoolKeyGenerationTest {
|
||||||
|
|
||||||
public PGPSecretKeyRing generateKey(KeySpec primaryKey, KeySpec subKey, String userId) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
|
public PGPSecretKeyRing generateKey(KeySpec primaryKey, KeySpec subKey, String userId) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withSubKey(subKey)
|
.setPrimaryKey(primaryKey)
|
||||||
.withPrimaryKey(primaryKey)
|
.addSubkey(subKey)
|
||||||
.withPrimaryUserId(userId)
|
.addUserId(userId)
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
return secretKeys;
|
return secretKeys;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,9 @@ public class CertificationKeyMustBeAbleToCertifyTest {
|
||||||
for (KeyType type : typesIncapableOfCreatingVerifications) {
|
for (KeyType type : typesIncapableOfCreatingVerifications) {
|
||||||
assertThrows(IllegalArgumentException.class, () -> PGPainless
|
assertThrows(IllegalArgumentException.class, () -> PGPainless
|
||||||
.generateKeyRing()
|
.generateKeyRing()
|
||||||
.withPrimaryKey(KeySpec
|
.setPrimaryKey(KeySpec.getBuilder(type, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.getBuilder(type, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
.addUserId("should@throw.ex")
|
||||||
.build())
|
.build());
|
||||||
.withPrimaryUserId("should@throw.ex")
|
|
||||||
.withoutPassphrase().build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,11 @@ public class GenerateEllipticCurveKeyTest {
|
||||||
public void generateEllipticCurveKeys(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
public void generateEllipticCurveKeys(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
||||||
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
||||||
PGPSecretKeyRing keyRing = PGPainless.generateKeyRing()
|
PGPSecretKeyRing keyRing = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS).build())
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
|
||||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||||
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.build())
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS))
|
||||||
.withPrimaryUserId(UserId.onlyEmail("alice@wonderland.lit").toString())
|
.addUserId(UserId.onlyEmail("alice@wonderland.lit").toString())
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertEquals(PublicKeyAlgorithm.EDDSA.getAlgorithmId(), keyRing.getPublicKey().getAlgorithm());
|
assertEquals(PublicKeyAlgorithm.EDDSA.getAlgorithmId(), keyRing.getPublicKey().getAlgorithm());
|
||||||
|
|
|
@ -47,16 +47,14 @@ public class GenerateKeyWithAdditionalUserIdTest {
|
||||||
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
||||||
Date expiration = new Date(DateUtil.now().getTime() + 60 * 1000);
|
Date expiration = new Date(DateUtil.now().getTime() + 60 * 1000);
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
KeyType.RSA(RsaLength._3072),
|
KeyType.RSA(RsaLength._3072),
|
||||||
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.ENCRYPT_COMMS)
|
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.ENCRYPT_COMMS))
|
||||||
.build())
|
.addUserId(UserId.onlyEmail("primary@user.id"))
|
||||||
.withPrimaryUserId(UserId.onlyEmail("primary@user.id"))
|
.addUserId(UserId.onlyEmail("additional@user.id"))
|
||||||
.withAdditionalUserId(UserId.onlyEmail("additional@user.id"))
|
.addUserId(UserId.onlyEmail("additional2@user.id"))
|
||||||
.withAdditionalUserId(UserId.onlyEmail("additional2@user.id"))
|
.addUserId("\ttrimThis@user.id ")
|
||||||
.withAdditionalUserId("\ttrimThis@user.id ")
|
|
||||||
.setExpirationDate(expiration)
|
.setExpirationDate(expiration)
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ import org.pgpainless.util.Passphrase;
|
||||||
* The issue is that the implementation of {@link Passphrase#emptyPassphrase()} would set the underlying
|
* The issue is that the implementation of {@link Passphrase#emptyPassphrase()} would set the underlying
|
||||||
* char array to null, which caused an NPE later on.
|
* char array to null, which caused an NPE later on.
|
||||||
*/
|
*/
|
||||||
public class GenerateWithEmptyPassphrase {
|
public class GenerateWithEmptyPassphraseTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories")
|
@MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories")
|
||||||
|
@ -46,12 +46,11 @@ public class GenerateWithEmptyPassphrase {
|
||||||
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
||||||
|
|
||||||
assertNotNull(PGPainless.generateKeyRing()
|
assertNotNull(PGPainless.generateKeyRing()
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
KeyType.RSA(RsaLength._3072),
|
KeyType.RSA(RsaLength._3072),
|
||||||
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.ENCRYPT_COMMS)
|
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.ENCRYPT_COMMS))
|
||||||
.build())
|
.addUserId("primary@user.id")
|
||||||
.withPrimaryUserId("primary@user.id")
|
.setPassphrase(Passphrase.emptyPassphrase())
|
||||||
.withPassphrase(Passphrase.emptyPassphrase())
|
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -221,16 +221,14 @@ public class KeyRingInfoTest {
|
||||||
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
ImplementationFactory.setFactoryImplementation(implementationFactory);
|
||||||
|
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
|
KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER))
|
||||||
|
.addSubkey(KeySpec.getBuilder(
|
||||||
KeyType.ECDH(EllipticCurve._BRAINPOOLP384R1),
|
KeyType.ECDH(EllipticCurve._BRAINPOOLP384R1),
|
||||||
KeyFlag.ENCRYPT_STORAGE).build())
|
KeyFlag.ENCRYPT_STORAGE))
|
||||||
.withSubKey(KeySpec.getBuilder(
|
.addSubkey(KeySpec.getBuilder(
|
||||||
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1), KeyFlag.SIGN_DATA)
|
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1), KeyFlag.SIGN_DATA))
|
||||||
.build())
|
.addUserId(UserId.newBuilder().withName("Alice").withEmail("alice@pgpainless.org").build())
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
|
||||||
KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER).build())
|
|
||||||
.withPrimaryUserId(UserId.newBuilder().withName("Alice").withEmail("alice@pgpainless.org").build())
|
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Iterator<PGPSecretKey> keys = secretKeys.iterator();
|
Iterator<PGPSecretKey> keys = secretKeys.iterator();
|
||||||
|
|
|
@ -51,16 +51,13 @@ public class UserIdRevocationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testRevocationWithoutRevocationAttributes() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
public void testRevocationWithoutRevocationAttributes() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS)
|
|
||||||
.build())
|
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
|
||||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||||
KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER)
|
KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER))
|
||||||
.build())
|
.addSubkey(KeySpec.getBuilder(
|
||||||
.withPrimaryUserId("primary@key.id")
|
KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS))
|
||||||
.withAdditionalUserId("secondary@key.id")
|
.addUserId("primary@key.id")
|
||||||
.withoutPassphrase()
|
.addUserId("secondary@key.id")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// make a copy with revoked subkey
|
// make a copy with revoked subkey
|
||||||
|
@ -92,15 +89,12 @@ public class UserIdRevocationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testRevocationWithRevocationReason() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
|
public void testRevocationWithRevocationReason() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS)
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
.build())
|
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
|
||||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||||
KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER)
|
KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER))
|
||||||
.build())
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS))
|
||||||
.withPrimaryUserId("primary@key.id")
|
.addUserId("primary@key.id")
|
||||||
.withAdditionalUserId("secondary@key.id")
|
.addUserId("secondary@key.id")
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
||||||
|
|
|
@ -47,12 +47,12 @@ public class BCUtilTest {
|
||||||
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
|
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
|
||||||
IOException {
|
IOException {
|
||||||
PGPSecretKeyRing sec = PGPainless.generateKeyRing()
|
PGPSecretKeyRing sec = PGPainless.generateKeyRing()
|
||||||
.withSubKey(KeySpec.getBuilder(KeyType.RSA(RsaLength._3072), KeyFlag.ENCRYPT_COMMS).build())
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
|
||||||
KeyType.RSA(RsaLength._3072),
|
KeyType.RSA(RsaLength._3072),
|
||||||
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.build())
|
.addSubkey(KeySpec.getBuilder(KeyType.RSA(RsaLength._3072), KeyFlag.ENCRYPT_COMMS))
|
||||||
.withPrimaryUserId("donald@duck.tails").withoutPassphrase().build();
|
.addUserId("donald@duck.tails")
|
||||||
|
.build();
|
||||||
|
|
||||||
PGPPublicKeyRing pub = KeyRingUtils.publicKeyRingFrom(sec);
|
PGPPublicKeyRing pub = KeyRingUtils.publicKeyRingFrom(sec);
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,12 @@ public class GuessPreferredHashAlgorithmTest {
|
||||||
@Test
|
@Test
|
||||||
public void guessPreferredHashAlgorithmsAssumesHashAlgoUsedBySelfSig() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
public void guessPreferredHashAlgorithmsAssumesHashAlgoUsedBySelfSig() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519),
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||||
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
||||||
.overridePreferredHashAlgorithms(new HashAlgorithm[] {})
|
.overridePreferredHashAlgorithms(new HashAlgorithm[] {})
|
||||||
.overridePreferredSymmetricKeyAlgorithms(new SymmetricKeyAlgorithm[] {})
|
.overridePreferredSymmetricKeyAlgorithms(new SymmetricKeyAlgorithm[] {})
|
||||||
.overridePreferredCompressionAlgorithms(new CompressionAlgorithm[] {})
|
.overridePreferredCompressionAlgorithms(new CompressionAlgorithm[] {}))
|
||||||
.build())
|
.addUserId("test@test.test")
|
||||||
.withPrimaryUserId("test@test.test")
|
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
PGPPublicKey publicKey = secretKeys.getPublicKey();
|
PGPPublicKey publicKey = secretKeys.getPublicKey();
|
||||||
|
|
|
@ -38,14 +38,13 @@ public class TestEncryptCommsStorageFlagsDifferentiated {
|
||||||
@Test
|
@Test
|
||||||
public void testThatEncryptionDifferentiatesBetweenPurposeKeyFlags() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
public void testThatEncryptionDifferentiatesBetweenPurposeKeyFlags() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
.withPrimaryKey(KeySpec.getBuilder(
|
.setPrimaryKey(KeySpec.getBuilder(
|
||||||
KeyType.RSA(RsaLength._3072),
|
KeyType.RSA(RsaLength._3072),
|
||||||
KeyFlag.CERTIFY_OTHER,
|
KeyFlag.CERTIFY_OTHER,
|
||||||
KeyFlag.SIGN_DATA,
|
KeyFlag.SIGN_DATA,
|
||||||
KeyFlag.ENCRYPT_STORAGE // no ENCRYPT_COMMS
|
KeyFlag.ENCRYPT_STORAGE // no ENCRYPT_COMMS
|
||||||
).build())
|
))
|
||||||
.withPrimaryUserId("cannot@encrypt.comms")
|
.addUserId("cannot@encrypt.comms")
|
||||||
.withoutPassphrase()
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
||||||
|
|
Loading…
Reference in a new issue