mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-26 22:32:07 +01:00
Ensure keyflags are set when adding userid
This commit is contained in:
parent
a6181218a2
commit
ab3ae15719
3 changed files with 47 additions and 27 deletions
|
@ -37,7 +37,7 @@ import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
|
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
|
||||||
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
|
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
|
||||||
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.KeyFlag;
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||||
import org.pgpainless.algorithm.SignatureType;
|
import org.pgpainless.algorithm.SignatureType;
|
||||||
|
@ -45,6 +45,7 @@ import org.pgpainless.implementation.ImplementationFactory;
|
||||||
import org.pgpainless.key.OpenPgpFingerprint;
|
import org.pgpainless.key.OpenPgpFingerprint;
|
||||||
import org.pgpainless.key.generation.KeyRingBuilder;
|
import org.pgpainless.key.generation.KeyRingBuilder;
|
||||||
import org.pgpainless.key.generation.KeySpec;
|
import org.pgpainless.key.generation.KeySpec;
|
||||||
|
import org.pgpainless.key.info.KeyRingInfo;
|
||||||
import org.pgpainless.key.protection.CachingSecretKeyRingProtector;
|
import org.pgpainless.key.protection.CachingSecretKeyRingProtector;
|
||||||
import org.pgpainless.key.protection.KeyRingProtectionSettings;
|
import org.pgpainless.key.protection.KeyRingProtectionSettings;
|
||||||
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
||||||
|
@ -58,6 +59,7 @@ import org.pgpainless.key.util.RevocationAttributes;
|
||||||
import org.pgpainless.signature.SignatureUtils;
|
import org.pgpainless.signature.SignatureUtils;
|
||||||
import org.pgpainless.signature.builder.PrimaryKeyBindingSignatureBuilder;
|
import org.pgpainless.signature.builder.PrimaryKeyBindingSignatureBuilder;
|
||||||
import org.pgpainless.signature.builder.SelfSignatureBuilder;
|
import org.pgpainless.signature.builder.SelfSignatureBuilder;
|
||||||
|
import org.pgpainless.signature.builder.SignatureFactory;
|
||||||
import org.pgpainless.signature.builder.SubkeyBindingSignatureBuilder;
|
import org.pgpainless.signature.builder.SubkeyBindingSignatureBuilder;
|
||||||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
|
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil;
|
import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil;
|
||||||
|
@ -67,11 +69,6 @@ import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
|
|
||||||
// Default algorithm for calculating private key checksums
|
|
||||||
// While I'd like to use something else, eg. SHA256, BC seems to lack support for
|
|
||||||
// calculating secret key checksums with algorithms other than SHA1.
|
|
||||||
private static final HashAlgorithm defaultDigestHashAlgorithm = HashAlgorithm.SHA1;
|
|
||||||
|
|
||||||
private PGPSecretKeyRing secretKeyRing;
|
private PGPSecretKeyRing secretKeyRing;
|
||||||
|
|
||||||
public SecretKeyRingEditor(PGPSecretKeyRing secretKeyRing) {
|
public SecretKeyRingEditor(PGPSecretKeyRing secretKeyRing) {
|
||||||
|
@ -98,8 +95,9 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
// add user-id certificate to primary key
|
// add user-id certificate to primary key
|
||||||
PGPSecretKey primaryKey = secretKeyIterator.next();
|
PGPSecretKey primaryKey = secretKeyIterator.next();
|
||||||
PGPPublicKey publicKey = primaryKey.getPublicKey();
|
PGPPublicKey publicKey = primaryKey.getPublicKey();
|
||||||
|
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing);
|
||||||
SelfSignatureBuilder builder = new SelfSignatureBuilder(primaryKey, protector);
|
List<KeyFlag> keyFlags = info.getKeyFlagsOf(info.getKeyId());
|
||||||
|
SelfSignatureBuilder builder = SignatureFactory.selfCertifyUserId(primaryKey, protector, signatureSubpacketCallback, keyFlags.toArray(new KeyFlag[0]));
|
||||||
builder.setSignatureType(SignatureType.POSITIVE_CERTIFICATION);
|
builder.setSignatureType(SignatureType.POSITIVE_CERTIFICATION);
|
||||||
builder.applyCallback(signatureSubpacketCallback);
|
builder.applyCallback(signatureSubpacketCallback);
|
||||||
PGPSignature signature = builder.build(publicKey, userId);
|
PGPSignature signature = builder.build(publicKey, userId);
|
||||||
|
@ -155,8 +153,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
PBESecretKeyDecryptor ringDecryptor = keyRingProtector.getDecryptor(primaryKey.getKeyID());
|
PBESecretKeyDecryptor ringDecryptor = keyRingProtector.getDecryptor(primaryKey.getKeyID());
|
||||||
PBESecretKeyEncryptor subKeyEncryptor = subKeyProtector.getEncryptor(secretSubKey.getKeyID());
|
PBESecretKeyEncryptor subKeyEncryptor = subKeyProtector.getEncryptor(secretSubKey.getKeyID());
|
||||||
|
|
||||||
PGPDigestCalculator digestCalculator =
|
PGPDigestCalculator digestCalculator = ImplementationFactory.getInstance().getV4FingerprintCalculator();
|
||||||
ImplementationFactory.getInstance().getPGPDigestCalculator(defaultDigestHashAlgorithm);
|
|
||||||
PGPContentSignerBuilder contentSignerBuilder =
|
PGPContentSignerBuilder contentSignerBuilder =
|
||||||
SignatureUtils.getPgpContentSignerBuilderForKey(primaryKey);
|
SignatureUtils.getPgpContentSignerBuilderForKey(primaryKey);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.pgpainless.key.util.OpenPgpKeyAttributeUtil;
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpackets;
|
import org.pgpainless.signature.subpackets.SignatureSubpackets;
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper;
|
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilder<B>> {
|
public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilder<B>> {
|
||||||
protected final PGPPrivateKey privateSigningKey;
|
protected final PGPPrivateKey privateSigningKey;
|
||||||
protected final PGPPublicKey publicSigningKey;
|
protected final PGPPublicKey publicSigningKey;
|
||||||
|
@ -34,7 +36,12 @@ public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilde
|
||||||
protected SignatureSubpackets unhashedSubpackets;
|
protected SignatureSubpackets unhashedSubpackets;
|
||||||
protected SignatureSubpackets hashedSubpackets;
|
protected SignatureSubpackets hashedSubpackets;
|
||||||
|
|
||||||
public AbstractSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
|
protected AbstractSignatureBuilder(SignatureType signatureType,
|
||||||
|
PGPSecretKey signingKey,
|
||||||
|
SecretKeyRingProtector protector,
|
||||||
|
HashAlgorithm hashAlgorithm,
|
||||||
|
SignatureSubpackets hashedSubpackets,
|
||||||
|
SignatureSubpackets unhashedSubpackets)
|
||||||
throws WrongPassphraseException {
|
throws WrongPassphraseException {
|
||||||
if (!isValidSignatureType(signatureType)) {
|
if (!isValidSignatureType(signatureType)) {
|
||||||
throw new IllegalArgumentException("Invalid signature type.");
|
throw new IllegalArgumentException("Invalid signature type.");
|
||||||
|
@ -42,26 +49,33 @@ public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilde
|
||||||
this.signatureType = signatureType;
|
this.signatureType = signatureType;
|
||||||
this.privateSigningKey = UnlockSecretKey.unlockSecretKey(signingKey, protector);
|
this.privateSigningKey = UnlockSecretKey.unlockSecretKey(signingKey, protector);
|
||||||
this.publicSigningKey = signingKey.getPublicKey();
|
this.publicSigningKey = signingKey.getPublicKey();
|
||||||
this.hashAlgorithm = negotiateHashAlgorithm(publicSigningKey);
|
this.hashAlgorithm = hashAlgorithm;
|
||||||
|
this.hashedSubpackets = hashedSubpackets;
|
||||||
|
this.unhashedSubpackets = unhashedSubpackets;
|
||||||
|
}
|
||||||
|
|
||||||
unhashedSubpackets = new SignatureSubpackets();
|
public AbstractSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
|
||||||
// Prepopulate hashed subpackets with default values (key-id etc.)
|
throws WrongPassphraseException {
|
||||||
hashedSubpackets = SignatureSubpackets.createHashedSubpackets(publicSigningKey);
|
this(
|
||||||
|
signatureType,
|
||||||
|
signingKey,
|
||||||
|
protector,
|
||||||
|
negotiateHashAlgorithm(signingKey.getPublicKey()),
|
||||||
|
SignatureSubpackets.createHashedSubpackets(signingKey.getPublicKey()),
|
||||||
|
SignatureSubpackets.createEmptySubpackets()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature)
|
public AbstractSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature)
|
||||||
throws WrongPassphraseException {
|
throws WrongPassphraseException {
|
||||||
SignatureType type = SignatureType.valueOf(archetypeSignature.getSignatureType());
|
this(
|
||||||
if (!isValidSignatureType(type)) {
|
SignatureType.valueOf(archetypeSignature.getSignatureType()),
|
||||||
throw new IllegalArgumentException("Invalid signature type.");
|
certificationKey,
|
||||||
}
|
protector,
|
||||||
this.signatureType = SignatureType.valueOf(archetypeSignature.getSignatureType());
|
negotiateHashAlgorithm(certificationKey.getPublicKey()),
|
||||||
this.privateSigningKey = UnlockSecretKey.unlockSecretKey(certificationKey, protector);
|
SignatureSubpackets.refreshHashedSubpackets(certificationKey.getPublicKey(), archetypeSignature),
|
||||||
this.publicSigningKey = certificationKey.getPublicKey();
|
SignatureSubpackets.refreshUnhashedSubpackets(archetypeSignature)
|
||||||
this.hashAlgorithm = negotiateHashAlgorithm(publicSigningKey);
|
);
|
||||||
|
|
||||||
unhashedSubpackets = SignatureSubpackets.refreshUnhashedSubpackets(archetypeSignature);
|
|
||||||
hashedSubpackets = SignatureSubpackets.refreshHashedSubpackets(publicSigningKey, archetypeSignature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,12 +84,17 @@ public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilde
|
||||||
* @param publicKey signing public key
|
* @param publicKey signing public key
|
||||||
* @return hash algorithm
|
* @return hash algorithm
|
||||||
*/
|
*/
|
||||||
protected HashAlgorithm negotiateHashAlgorithm(PGPPublicKey publicKey) {
|
protected static HashAlgorithm negotiateHashAlgorithm(PGPPublicKey publicKey) {
|
||||||
Set<HashAlgorithm> hashAlgorithmPreferences = OpenPgpKeyAttributeUtil.getOrGuessPreferredHashAlgorithms(publicKey);
|
Set<HashAlgorithm> hashAlgorithmPreferences = OpenPgpKeyAttributeUtil.getOrGuessPreferredHashAlgorithms(publicKey);
|
||||||
return HashAlgorithmNegotiator.negotiateSignatureHashAlgorithm(PGPainless.getPolicy())
|
return HashAlgorithmNegotiator.negotiateSignatureHashAlgorithm(PGPainless.getPolicy())
|
||||||
.negotiateHashAlgorithm(hashAlgorithmPreferences);
|
.negotiateHashAlgorithm(hashAlgorithmPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public B overrideHashAlgorithm(@Nonnull HashAlgorithm hashAlgorithm) {
|
||||||
|
this.hashAlgorithm = hashAlgorithm;
|
||||||
|
return (B) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the builders {@link SignatureType}.
|
* Set the builders {@link SignatureType}.
|
||||||
* Note that only those types who are valid for the concrete subclass of this {@link AbstractSignatureBuilder}
|
* Note that only those types who are valid for the concrete subclass of this {@link AbstractSignatureBuilder}
|
||||||
|
|
|
@ -103,6 +103,10 @@ public class SignatureSubpackets
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SignatureSubpackets createEmptySubpackets() {
|
||||||
|
return new SignatureSubpackets();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SignatureSubpackets setIssuerFingerprintAndKeyId(PGPPublicKey key) {
|
public SignatureSubpackets setIssuerFingerprintAndKeyId(PGPPublicKey key) {
|
||||||
setIssuerKeyId(key.getKeyID());
|
setIssuerKeyId(key.getKeyID());
|
||||||
|
|
Loading…
Reference in a new issue