1
0
Fork 0
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:
Paul Schaub 2021-11-12 15:07:09 +01:00
parent a6181218a2
commit ab3ae15719
3 changed files with 47 additions and 27 deletions

View file

@ -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);

View file

@ -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}

View file

@ -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());