1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-23 04:42:06 +01:00

Rework user-id revocation to use subpackets callback API

This commit is contained in:
Paul Schaub 2021-11-16 15:35:17 +01:00
parent 24aebfaf63
commit 25c95804ce
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
3 changed files with 51 additions and 26 deletions

View file

@ -315,7 +315,33 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
@Override @Override
public SecretKeyRingEditorInterface revokeUserId(String userId, public SecretKeyRingEditorInterface revokeUserId(String userId,
SecretKeyRingProtector secretKeyRingProtector, SecretKeyRingProtector secretKeyRingProtector,
RevocationAttributes revocationAttributes) @Nullable RevocationAttributes revocationAttributes)
throws PGPException {
if (revocationAttributes != null) {
RevocationAttributes.Reason reason = revocationAttributes.getReason();
if (reason != RevocationAttributes.Reason.NO_REASON
&& reason != RevocationAttributes.Reason.USER_ID_NO_LONGER_VALID) {
throw new IllegalArgumentException("Revocation reason must either be NO_REASON or USER_ID_NO_LONGER_VALID");
}
}
RevocationSignatureSubpackets.Callback callback = new RevocationSignatureSubpackets.Callback() {
@Override
public void modifyHashedSubpackets(RevocationSignatureSubpackets hashedSubpackets) {
if (revocationAttributes != null) {
hashedSubpackets.setRevocationReason(false, revocationAttributes);
}
}
};
return revokeUserId(userId, secretKeyRingProtector, callback);
}
@Override
public SecretKeyRingEditorInterface revokeUserId(
String userId,
SecretKeyRingProtector secretKeyRingProtector,
@Nullable RevocationSignatureSubpackets.Callback subpacketCallback)
throws PGPException { throws PGPException {
Iterator<String> userIds = secretKeyRing.getPublicKey().getUserIDs(); Iterator<String> userIds = secretKeyRing.getPublicKey().getUserIDs();
boolean found = false; boolean found = false;
@ -328,38 +354,23 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
if (!found) { if (!found) {
throw new NoSuchElementException("No user-id '" + userId + "' found on the key."); throw new NoSuchElementException("No user-id '" + userId + "' found on the key.");
} }
return doRevokeUserId(userId, secretKeyRingProtector, revocationAttributes); return doRevokeUserId(userId, secretKeyRingProtector, subpacketCallback);
} }
private SecretKeyRingEditorInterface doRevokeUserId(String userId, private SecretKeyRingEditorInterface doRevokeUserId(String userId,
SecretKeyRingProtector protector, SecretKeyRingProtector protector,
RevocationAttributes revocationAttributes) @Nullable RevocationSignatureSubpackets.Callback callback)
throws PGPException { throws PGPException {
PGPSecretKey primarySecretKey = secretKeyRing.getSecretKey(); PGPSecretKey primarySecretKey = secretKeyRing.getSecretKey();
PGPPublicKey primaryPublicKey = primarySecretKey.getPublicKey(); PGPPublicKey primaryPublicKey = primarySecretKey.getPublicKey();
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primarySecretKey, protector); RevocationSignatureBuilder signatureBuilder = new RevocationSignatureBuilder(
SignatureType.CERTIFICATION_REVOCATION,
primarySecretKey,
protector);
PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator(); signatureBuilder.applyCallback(callback);
subpacketGenerator.setSignatureCreationTime(false, new Date());
subpacketGenerator.setRevocable(false, false);
subpacketGenerator.setIssuerFingerprint(false, primarySecretKey);
if (revocationAttributes != null) {
RevocationAttributes.Reason reason = revocationAttributes.getReason();
if (reason != RevocationAttributes.Reason.NO_REASON
&& reason != RevocationAttributes.Reason.USER_ID_NO_LONGER_VALID) {
throw new IllegalArgumentException("Revocation reason must either be NO_REASON or USER_ID_NO_LONGER_VALID");
}
subpacketGenerator.setRevocationReason(
false,
revocationAttributes.getReason().code(),
revocationAttributes.getDescription());
}
PGPSignatureGenerator signatureGenerator = SignatureUtils.getSignatureGeneratorFor(primarySecretKey); PGPSignature revocationSignature = signatureBuilder.build(userId);
signatureGenerator.setHashedSubpackets(subpacketGenerator.generate());
signatureGenerator.init(SignatureType.CERTIFICATION_REVOCATION.getCode(), privateKey);
PGPSignature revocationSignature = signatureGenerator.generateCertification(userId, primaryPublicKey);
primaryPublicKey = PGPPublicKey.addCertification(primaryPublicKey, userId, revocationSignature); primaryPublicKey = PGPPublicKey.addCertification(primaryPublicKey, userId, revocationSignature);
PGPPublicKeyRing publicKeyRing = KeyRingUtils.publicKeyRingFrom(secretKeyRing); PGPPublicKeyRing publicKeyRing = KeyRingUtils.publicKeyRingFrom(secretKeyRing);

View file

@ -190,7 +190,7 @@ public interface SecretKeyRingEditorInterface {
default SecretKeyRingEditorInterface revokeUserId(String userId, default SecretKeyRingEditorInterface revokeUserId(String userId,
SecretKeyRingProtector secretKeyRingProtector) SecretKeyRingProtector secretKeyRingProtector)
throws PGPException { throws PGPException {
return revokeUserId(userId, secretKeyRingProtector, null); return revokeUserId(userId, secretKeyRingProtector, (RevocationAttributes) null);
} }
/** /**
@ -203,7 +203,12 @@ public interface SecretKeyRingEditorInterface {
*/ */
SecretKeyRingEditorInterface revokeUserId(String userId, SecretKeyRingEditorInterface revokeUserId(String userId,
SecretKeyRingProtector secretKeyRingProtector, SecretKeyRingProtector secretKeyRingProtector,
RevocationAttributes revocationAttributes) @Nullable RevocationAttributes revocationAttributes)
throws PGPException;
SecretKeyRingEditorInterface revokeUserId(String userId,
SecretKeyRingProtector secretKeyRingProtector,
@Nullable RevocationSignatureSubpackets.Callback subpacketCallback)
throws PGPException; throws PGPException;
/** /**

View file

@ -20,6 +20,7 @@ public class RevocationSignatureBuilder extends AbstractSignatureBuilder<Revocat
public RevocationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws WrongPassphraseException { public RevocationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws WrongPassphraseException {
super(signatureType, signingKey, protector); super(signatureType, signingKey, protector);
getHashedSubpackets().setRevocable(true, false);
} }
@Override @Override
@ -60,4 +61,12 @@ public class RevocationSignatureBuilder extends AbstractSignatureBuilder<Revocat
return signatureGenerator.generateCertification(publicSigningKey, revokeeSubkey); return signatureGenerator.generateCertification(publicSigningKey, revokeeSubkey);
} }
} }
public PGPSignature build(String revokeeUserId) throws PGPException {
PGPSignatureGenerator signatureGenerator = buildAndInitSignatureGenerator();
if (signatureType != SignatureType.CERTIFICATION_REVOCATION) {
throw new IllegalArgumentException("Signature type is != CERTIFICATION_REVOCATION.");
}
return signatureGenerator.generateCertification(revokeeUserId, publicSigningKey);
}
} }