mirror of
https://codeberg.org/PGPainless/bc-sop.git
synced 2025-09-09 11:19:41 +02:00
Implement different key generation profiles
This commit is contained in:
parent
0a196432ff
commit
a083d0ebfa
2 changed files with 159 additions and 20 deletions
|
@ -1,10 +1,15 @@
|
||||||
package org.pgpainless.bouncycastle.sop.operation;
|
package org.pgpainless.bouncycastle.sop.operation;
|
||||||
|
|
||||||
|
import org.bouncycastle.bcpg.PublicKeyPacket;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||||
|
import org.bouncycastle.openpgp.api.KeyPairGeneratorCallback;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
import org.bouncycastle.openpgp.api.OpenPGPApi;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPV6KeyGenerator;
|
import org.bouncycastle.openpgp.api.OpenPGPKeyGenerator;
|
||||||
|
import org.bouncycastle.openpgp.operator.PGPKeyPairGenerator;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import sop.Profile;
|
||||||
import sop.Ready;
|
import sop.Ready;
|
||||||
import sop.exception.SOPGPException;
|
import sop.exception.SOPGPException;
|
||||||
import sop.operation.GenerateKey;
|
import sop.operation.GenerateKey;
|
||||||
|
@ -13,6 +18,7 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -20,10 +26,17 @@ public class BCGenerateKey
|
||||||
extends AbstractBCOperation
|
extends AbstractBCOperation
|
||||||
implements GenerateKey {
|
implements GenerateKey {
|
||||||
|
|
||||||
|
public static final Profile DEFAULT = new Profile("default", "Use the implementer's recommendations.");
|
||||||
|
public static final Profile SECURITY = new Profile("security", "Higher security, maybe reduced performance.");
|
||||||
|
public static final Profile PERFORMANCE = new Profile("performance", "Higher performance, maybe reduced security.");
|
||||||
|
public static final Profile COMPATIBILITY = new Profile("compatibility", "Use algorithms and features from rfc4480.");
|
||||||
|
public static final List<Profile> PROFILES = Arrays.asList(DEFAULT, SECURITY, PERFORMANCE, COMPATIBILITY);
|
||||||
|
|
||||||
private boolean armor = true;
|
private boolean armor = true;
|
||||||
private boolean signOnly = false;
|
private boolean signOnly = false;
|
||||||
private final List<String> userIds = new ArrayList<>();
|
private final List<String> userIds = new ArrayList<>();
|
||||||
private char[] passphrase;
|
private char[] passphrase;
|
||||||
|
private Profile profile = DEFAULT;
|
||||||
|
|
||||||
public BCGenerateKey(OpenPGPApi api) {
|
public BCGenerateKey(OpenPGPApi api) {
|
||||||
super(api);
|
super(api);
|
||||||
|
@ -37,24 +50,10 @@ public class BCGenerateKey
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(@NotNull OutputStream outputStream) throws IOException
|
public void writeTo(@NotNull OutputStream outputStream) throws IOException
|
||||||
{
|
{
|
||||||
OpenPGPV6KeyGenerator generator;
|
|
||||||
try {
|
|
||||||
generator = api.generateKey(new Date());
|
|
||||||
} catch (PGPException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
OpenPGPKey key;
|
OpenPGPKey key;
|
||||||
try
|
try {
|
||||||
{
|
OpenPGPKeyGenerator.WithPrimaryKey builder = generatorForProfile(api, profile, signOnly);
|
||||||
OpenPGPV6KeyGenerator.WithPrimaryKey builder;
|
|
||||||
if (signOnly)
|
|
||||||
{
|
|
||||||
builder = generator.signOnlyKey();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builder = generator.ed25519x25519Key(null);
|
|
||||||
}
|
|
||||||
for (String userId : userIds)
|
for (String userId : userIds)
|
||||||
{
|
{
|
||||||
builder.addUserId(userId);
|
builder.addUserId(userId);
|
||||||
|
@ -78,6 +77,135 @@ public class BCGenerateKey
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OpenPGPKeyGenerator.WithPrimaryKey generatorForProfile(OpenPGPApi api,
|
||||||
|
Profile profile,
|
||||||
|
boolean signOnly)
|
||||||
|
throws PGPException {
|
||||||
|
Date creationTime = new Date();
|
||||||
|
OpenPGPKeyGenerator.WithPrimaryKey builder;
|
||||||
|
switch (profile.getName())
|
||||||
|
{
|
||||||
|
case "performance":
|
||||||
|
builder = api.generateKey(PublicKeyPacket.VERSION_6, creationTime, false)
|
||||||
|
.withPrimaryKey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateEd25519KeyPair();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addSigningSubkey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateEd25519KeyPair();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!signOnly)
|
||||||
|
{
|
||||||
|
builder.addEncryptionSubkey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateX25519KeyPair();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "compatibility":
|
||||||
|
builder = api.generateKey(PublicKeyPacket.VERSION_4, creationTime, false)
|
||||||
|
.withPrimaryKey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateRsaKeyPair(3072);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addSigningSubkey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateRsaKeyPair(3072);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!signOnly)
|
||||||
|
{
|
||||||
|
builder.addEncryptionSubkey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateRsaKeyPair(3072);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "default":
|
||||||
|
builder = api.generateKey(PublicKeyPacket.VERSION_6, creationTime, true)
|
||||||
|
.withPrimaryKey()
|
||||||
|
.addSigningSubkey();
|
||||||
|
if (!signOnly)
|
||||||
|
{
|
||||||
|
builder.addEncryptionSubkey();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "security":
|
||||||
|
builder = api.generateKey(PublicKeyPacket.VERSION_6, creationTime, true)
|
||||||
|
.withPrimaryKey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateEd448KeyPair();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addSigningSubkey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateEd448KeyPair();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!signOnly)
|
||||||
|
{
|
||||||
|
builder.addEncryptionSubkey(new KeyPairGeneratorCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
|
||||||
|
throws PGPException
|
||||||
|
{
|
||||||
|
return generator.generateX448KeyPair();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new SOPGPException.UnsupportedProfile("generate-key", profile.getName());
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public GenerateKey noArmor() {
|
public GenerateKey noArmor() {
|
||||||
|
@ -102,7 +230,13 @@ public class BCGenerateKey
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public GenerateKey profile(@NotNull String s) {
|
public GenerateKey profile(@NotNull String s) {
|
||||||
return this;
|
for (Profile p : PROFILES) {
|
||||||
|
if (p.getName().equals(s)) {
|
||||||
|
this.profile = p;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new SOPGPException.UnsupportedProfile("generate-key", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import sop.Profile;
|
import sop.Profile;
|
||||||
import sop.operation.ListProfiles;
|
import sop.operation.ListProfiles;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BCListProfiles
|
public class BCListProfiles
|
||||||
|
@ -18,6 +19,10 @@ public class BCListProfiles
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<Profile> subcommand(@NotNull String s) {
|
public List<Profile> subcommand(@NotNull String s) {
|
||||||
return List.of();
|
switch (s) {
|
||||||
|
case "generate-key":
|
||||||
|
return BCGenerateKey.PROFILES;
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue