mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-18 02:12:06 +01:00
Support version 3 signature packets
This commit is contained in:
parent
6c2331d4e6
commit
30771f470a
3 changed files with 75 additions and 3 deletions
|
@ -158,8 +158,10 @@ public abstract class SignatureValidator {
|
||||||
@Override
|
@Override
|
||||||
public void verify(PGPSignature signature) throws SignatureValidationException {
|
public void verify(PGPSignature signature) throws SignatureValidationException {
|
||||||
signatureIsNotMalformed(signingKey).verify(signature);
|
signatureIsNotMalformed(signingKey).verify(signature);
|
||||||
signatureDoesNotHaveCriticalUnknownNotations(policy.getNotationRegistry()).verify(signature);
|
if (signature.getVersion() >= 4) {
|
||||||
signatureDoesNotHaveCriticalUnknownSubpackets().verify(signature);
|
signatureDoesNotHaveCriticalUnknownNotations(policy.getNotationRegistry()).verify(signature);
|
||||||
|
signatureDoesNotHaveCriticalUnknownSubpackets().verify(signature);
|
||||||
|
}
|
||||||
signatureUsesAcceptableHashAlgorithm(policy).verify(signature);
|
signatureUsesAcceptableHashAlgorithm(policy).verify(signature);
|
||||||
signatureUsesAcceptablePublicKeyAlgorithm(policy, signingKey).verify(signature);
|
signatureUsesAcceptablePublicKeyAlgorithm(policy, signingKey).verify(signature);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +375,9 @@ public abstract class SignatureValidator {
|
||||||
return new SignatureValidator() {
|
return new SignatureValidator() {
|
||||||
@Override
|
@Override
|
||||||
public void verify(PGPSignature signature) throws SignatureValidationException {
|
public void verify(PGPSignature signature) throws SignatureValidationException {
|
||||||
signatureHasHashedCreationTime().verify(signature);
|
if (signature.getVersion() >= 4) {
|
||||||
|
signatureHasHashedCreationTime().verify(signature);
|
||||||
|
}
|
||||||
signatureDoesNotPredateSigningKey(creator).verify(signature);
|
signatureDoesNotPredateSigningKey(creator).verify(signature);
|
||||||
if (signature.getSignatureType() != SignatureType.PRIMARYKEY_BINDING.getCode()) {
|
if (signature.getSignatureType() != SignatureType.PRIMARYKEY_BINDING.getCode()) {
|
||||||
signatureDoesNotPredateSigningKeyBindingDate(creator).verify(signature);
|
signatureDoesNotPredateSigningKeyBindingDate(creator).verify(signature);
|
||||||
|
|
|
@ -141,6 +141,9 @@ public final class SignatureSubpacketsUtil {
|
||||||
* @return signature creation time subpacket
|
* @return signature creation time subpacket
|
||||||
*/
|
*/
|
||||||
public static @Nullable SignatureCreationTime getSignatureCreationTime(PGPSignature signature) {
|
public static @Nullable SignatureCreationTime getSignatureCreationTime(PGPSignature signature) {
|
||||||
|
if (signature.getVersion() == 3) {
|
||||||
|
return new SignatureCreationTime(false, signature.getCreationTime());
|
||||||
|
}
|
||||||
return hashed(signature, SignatureSubpacket.signatureCreationTime);
|
return hashed(signature, SignatureSubpacket.signatureCreationTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
|
import org.bouncycastle.openpgp.PGPV3SignatureGenerator;
|
||||||
|
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
|
||||||
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.SignatureType;
|
||||||
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
|
import org.pgpainless.key.TestKeys;
|
||||||
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class VerifyVersion3SignaturePacketTest {
|
||||||
|
|
||||||
|
|
||||||
|
protected static final byte[] DATA = "hello".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void verifyDetachedVersion3Signature() throws PGPException, IOException {
|
||||||
|
PGPSignature version3Signature = generateV3Signature();
|
||||||
|
|
||||||
|
ConsumerOptions options = new ConsumerOptions()
|
||||||
|
.addVerificationCert(TestKeys.getEmilPublicKeyRing())
|
||||||
|
.addVerificationOfDetachedSignatures(new ByteArrayInputStream(version3Signature.getEncoded()));
|
||||||
|
|
||||||
|
DecryptionStream verifier = PGPainless.decryptAndOrVerify()
|
||||||
|
.onInputStream(new ByteArrayInputStream(DATA))
|
||||||
|
.withOptions(options);
|
||||||
|
|
||||||
|
OpenPgpMetadata metadata = processSignedData(verifier);
|
||||||
|
assertTrue(metadata.containsVerifiedSignatureFrom(TestKeys.getEmilPublicKeyRing()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PGPSignature generateV3Signature() throws IOException, PGPException {
|
||||||
|
PGPContentSignerBuilder builder = ImplementationFactory.getInstance().getPGPContentSignerBuilder(PublicKeyAlgorithm.ECDSA, HashAlgorithm.SHA512);
|
||||||
|
PGPV3SignatureGenerator signatureGenerator = new PGPV3SignatureGenerator(builder);
|
||||||
|
|
||||||
|
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();
|
||||||
|
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
||||||
|
PGPPrivateKey privateKey = secretKeys.getSecretKey().extractPrivateKey(protector.getDecryptor(secretKeys.getSecretKey().getKeyID()));
|
||||||
|
|
||||||
|
signatureGenerator.init(SignatureType.CANONICAL_TEXT_DOCUMENT.getCode(), privateKey);
|
||||||
|
signatureGenerator.update(DATA);
|
||||||
|
|
||||||
|
return signatureGenerator.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenPgpMetadata processSignedData(DecryptionStream verifier) throws IOException {
|
||||||
|
Streams.drain(verifier);
|
||||||
|
verifier.close();
|
||||||
|
return verifier.getResult();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue