1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-12-06 20:31:08 +01:00

SigningOptions: Add methods to sign with a single, chosen signing subkey

This commit is contained in:
Paul Schaub 2023-06-08 14:04:06 +02:00
parent 5aabd1ced4
commit 1fca51d771
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
2 changed files with 270 additions and 0 deletions

View file

@ -242,6 +242,69 @@ public final class SigningOptions {
return this;
}
/**
* Create a binary inline signature using the signing key with the given keyId.
*
* @param secretKeyDecryptor decryptor to unlock the secret key
* @param secretKey secret key ring
* @param keyId keyId of the signing (sub-)key
* @return builder
* @throws PGPException if the secret key cannot be unlocked or if no signing method can be created.
* @throws KeyException.UnacceptableSigningKeyException if the key ring does not carry any signing-capable subkeys
* @throws KeyException.MissingSecretKeyException if the key ring does not contain the identified secret key
*/
@Nonnull
public SigningOptions addInlineSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
long keyId) throws PGPException {
return addInlineSignature(secretKeyDecryptor, secretKey, keyId, DocumentSignatureType.BINARY_DOCUMENT, null);
}
/**
* Create an inline signature using the signing key with the given keyId.
*
* @param secretKeyDecryptor decryptor to unlock the secret key
* @param secretKey secret key ring
* @param keyId keyId of the signing (sub-)key
* @param signatureType signature type
* @param subpacketsCallback callback to modify the signatures subpackets
* @return builder
* @throws PGPException if the secret key cannot be unlocked or if no signing method can be created.
* @throws KeyException.UnacceptableSigningKeyException if the key ring does not carry any signing-capable subkeys
* @throws KeyException.MissingSecretKeyException if the key ring does not contain the identified secret key
*/
@Nonnull
public SigningOptions addInlineSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
long keyId,
@Nonnull DocumentSignatureType signatureType,
@Nullable BaseSignatureSubpackets.Callback subpacketsCallback) throws PGPException {
KeyRingInfo keyRingInfo = PGPainless.inspectKeyRing(secretKey);
List<PGPPublicKey> signingPubKeys = keyRingInfo.getSigningSubkeys();
if (signingPubKeys.isEmpty()) {
throw new KeyException.UnacceptableSigningKeyException(OpenPgpFingerprint.of(secretKey));
}
for (PGPPublicKey signingPubKey : signingPubKeys) {
if (signingPubKey.getKeyID() == keyId) {
PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID());
if (signingSecKey == null) {
throw new KeyException.MissingSecretKeyException(OpenPgpFingerprint.of(secretKey), signingPubKey.getKeyID());
}
PGPPrivateKey signingSubkey = UnlockSecretKey.unlockSecretKey(signingSecKey, secretKeyDecryptor);
Set<HashAlgorithm> hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.getKeyID());
HashAlgorithm hashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, PGPainless.getPolicy());
addSigningMethod(secretKey, signingSubkey, subpacketsCallback, hashAlgorithm, signatureType, false);
return this;
}
}
throw new KeyException.MissingSecretKeyException(OpenPgpFingerprint.of(secretKey), keyId);
}
/**
* Add detached signatures with all key rings from the provided secret key ring collection.
*
@ -385,6 +448,68 @@ public final class SigningOptions {
return this;
}
/**
* Create a detached binary signature using the signing key with the given keyId.
*
* @param secretKeyDecryptor decryptor to unlock the secret key
* @param secretKey secret key ring
* @param keyId keyId of the signing (sub-)key
* @return builder
* @throws PGPException if the secret key cannot be unlocked or if no signing method can be created.
* @throws KeyException.UnacceptableSigningKeyException if the key ring does not carry any signing-capable subkeys
* @throws KeyException.MissingSecretKeyException if the key ring does not contain the identified secret key
*/
@Nonnull
public SigningOptions addDetachedSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
long keyId) throws PGPException {
return addDetachedSignature(secretKeyDecryptor, secretKey, keyId, DocumentSignatureType.BINARY_DOCUMENT, null);
}
/**
* Create a detached signature using the signing key with the given keyId.
*
* @param secretKeyDecryptor decryptor to unlock the secret key
* @param secretKey secret key ring
* @param keyId keyId of the signing (sub-)key
* @param signatureType signature type
* @param subpacketsCallback callback to modify the signatures subpackets
* @return builder
* @throws PGPException if the secret key cannot be unlocked or if no signing method can be created.
* @throws KeyException.UnacceptableSigningKeyException if the key ring does not carry any signing-capable subkeys
* @throws KeyException.MissingSecretKeyException if the key ring does not contain the identified secret key
*/
@Nonnull
public SigningOptions addDetachedSignature(@Nonnull SecretKeyRingProtector secretKeyDecryptor,
@Nonnull PGPSecretKeyRing secretKey,
long keyId,
@Nonnull DocumentSignatureType signatureType,
@Nullable BaseSignatureSubpackets.Callback subpacketsCallback) throws PGPException {
KeyRingInfo keyRingInfo = PGPainless.inspectKeyRing(secretKey);
List<PGPPublicKey> signingPubKeys = keyRingInfo.getSigningSubkeys();
if (signingPubKeys.isEmpty()) {
throw new KeyException.UnacceptableSigningKeyException(OpenPgpFingerprint.of(secretKey));
}
for (PGPPublicKey signingPubKey : signingPubKeys) {
if (signingPubKey.getKeyID() == keyId) {
PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID());
if (signingSecKey == null) {
throw new KeyException.MissingSecretKeyException(OpenPgpFingerprint.of(secretKey), signingPubKey.getKeyID());
}
PGPPrivateKey signingSubkey = UnlockSecretKey.unlockSecretKey(signingSecKey, secretKeyDecryptor);
Set<HashAlgorithm> hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.getKeyID());
HashAlgorithm hashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, PGPainless.getPolicy());
addSigningMethod(secretKey, signingSubkey, subpacketsCallback, hashAlgorithm, signatureType, true);
return this;
}
}
throw new KeyException.MissingSecretKeyException(OpenPgpFingerprint.of(secretKey), keyId);
}
private void addSigningMethod(@Nonnull PGPSecretKeyRing secretKey,
@Nonnull PGPPrivateKey signingSubkey,
@Nullable BaseSignatureSubpackets.Callback subpacketCallback,