mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 04:42:06 +01:00
Use OpenPgpV4Fingerprint class
This commit is contained in:
parent
d53501c9cd
commit
fb2db94839
8 changed files with 171 additions and 59 deletions
|
@ -48,6 +48,7 @@ import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
|
||||||
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
||||||
import org.pgpainless.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
|
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
import org.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
|
||||||
public final class DecryptionStreamFactory {
|
public final class DecryptionStreamFactory {
|
||||||
|
@ -63,7 +64,7 @@ public final class DecryptionStreamFactory {
|
||||||
private final PainlessResult.Builder resultBuilder = PainlessResult.getBuilder();
|
private final PainlessResult.Builder resultBuilder = PainlessResult.getBuilder();
|
||||||
private final PGPContentVerifierBuilderProvider verifierBuilderProvider = new BcPGPContentVerifierBuilderProvider();
|
private final PGPContentVerifierBuilderProvider verifierBuilderProvider = new BcPGPContentVerifierBuilderProvider();
|
||||||
private final KeyFingerPrintCalculator fingerCalc = new BcKeyFingerprintCalculator();
|
private final KeyFingerPrintCalculator fingerCalc = new BcKeyFingerprintCalculator();
|
||||||
private final Map<Long, PGPOnePassSignature> verifiableOnePassSignatures = new HashMap<>();
|
private final Map<OpenPgpV4Fingerprint, PGPOnePassSignature> verifiableOnePassSignatures = new HashMap<>();
|
||||||
|
|
||||||
private DecryptionStreamFactory(PGPSecretKeyRingCollection decryptionKeys,
|
private DecryptionStreamFactory(PGPSecretKeyRingCollection decryptionKeys,
|
||||||
SecretKeyRingProtector decryptor,
|
SecretKeyRingProtector decryptor,
|
||||||
|
@ -162,7 +163,7 @@ public final class DecryptionStreamFactory {
|
||||||
LOGGER.log(LEVEL, "Found respective secret key " + Long.toHexString(keyId));
|
LOGGER.log(LEVEL, "Found respective secret key " + Long.toHexString(keyId));
|
||||||
encryptedSessionKey = encryptedData;
|
encryptedSessionKey = encryptedData;
|
||||||
decryptionKey = secretKey.extractPrivateKey(decryptionKeyDecryptor.getDecryptor(keyId));
|
decryptionKey = secretKey.extractPrivateKey(decryptionKeyDecryptor.getDecryptor(keyId));
|
||||||
resultBuilder.setDecryptionKeyId(keyId);
|
resultBuilder.setDecryptionFingerprint(new OpenPgpV4Fingerprint(secretKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +199,7 @@ public final class DecryptionStreamFactory {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
PGPOnePassSignature signature = iterator.next();
|
PGPOnePassSignature signature = iterator.next();
|
||||||
final long keyId = signature.getKeyID();
|
final long keyId = signature.getKeyID();
|
||||||
resultBuilder.addSignatureKeyId(keyId);
|
resultBuilder.addUnverifiedSignatureKeyId(keyId);
|
||||||
|
|
||||||
LOGGER.log(LEVEL, "Message contains OnePassSignature from " + Long.toHexString(keyId));
|
LOGGER.log(LEVEL, "Message contains OnePassSignature from " + Long.toHexString(keyId));
|
||||||
|
|
||||||
|
@ -236,7 +237,7 @@ public final class DecryptionStreamFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
signature.init(verifierBuilderProvider, verificationKey);
|
signature.init(verifierBuilderProvider, verificationKey);
|
||||||
verifiableOnePassSignatures.put(keyId, signature);
|
verifiableOnePassSignatures.put(new OpenPgpV4Fingerprint(verificationKey), signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,36 +19,39 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.pgpainless.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
|
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
public class PainlessResult {
|
public class PainlessResult {
|
||||||
|
|
||||||
private final Set<Long> recipientKeyIds;
|
private final Set<Long> recipientKeyIds;
|
||||||
private final Long decryptionKeyId;
|
private final OpenPgpV4Fingerprint decryptionFingerprint;
|
||||||
|
private final Set<Long> unverifiedSignatureKeyIds;
|
||||||
|
private final Set<OpenPgpV4Fingerprint> verifiedSignaturesFingerprints;
|
||||||
|
|
||||||
private final SymmetricKeyAlgorithm symmetricKeyAlgorithm;
|
private final SymmetricKeyAlgorithm symmetricKeyAlgorithm;
|
||||||
private final CompressionAlgorithm compressionAlgorithm;
|
private final CompressionAlgorithm compressionAlgorithm;
|
||||||
private final boolean integrityProtected;
|
private final boolean integrityProtected;
|
||||||
private final Set<Long> signatureKeyIds;
|
|
||||||
private final Set<Long> verifiedSignatureKeyIds;
|
|
||||||
|
|
||||||
public PainlessResult(Set<Long> recipientKeyIds,
|
public PainlessResult(Set<Long> recipientKeyIds,
|
||||||
Long decryptionKeyId,
|
OpenPgpV4Fingerprint decryptionFingerprint,
|
||||||
SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
||||||
CompressionAlgorithm algorithm,
|
CompressionAlgorithm algorithm,
|
||||||
boolean integrityProtected,
|
boolean integrityProtected,
|
||||||
Set<Long> signatureKeyIds,
|
Set<Long> unverifiedSignatureKeyIds,
|
||||||
Set<Long> verifiedSignatureKeyIds) {
|
Set<OpenPgpV4Fingerprint> verifiedSignaturesFingerprints) {
|
||||||
|
|
||||||
this.recipientKeyIds = Collections.unmodifiableSet(recipientKeyIds);
|
this.recipientKeyIds = Collections.unmodifiableSet(recipientKeyIds);
|
||||||
this.decryptionKeyId = decryptionKeyId;
|
this.decryptionFingerprint = decryptionFingerprint;
|
||||||
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
|
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
|
||||||
this.compressionAlgorithm = algorithm;
|
this.compressionAlgorithm = algorithm;
|
||||||
this.integrityProtected = integrityProtected;
|
this.integrityProtected = integrityProtected;
|
||||||
this.signatureKeyIds = Collections.unmodifiableSet(signatureKeyIds);
|
this.unverifiedSignatureKeyIds = Collections.unmodifiableSet(unverifiedSignatureKeyIds);
|
||||||
this.verifiedSignatureKeyIds = Collections.unmodifiableSet(verifiedSignatureKeyIds);
|
this.verifiedSignaturesFingerprints = Collections.unmodifiableSet(verifiedSignaturesFingerprints);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Long> getRecipientKeyIds() {
|
public Set<Long> getRecipientKeyIds() {
|
||||||
|
@ -59,8 +62,8 @@ public class PainlessResult {
|
||||||
return !getRecipientKeyIds().isEmpty();
|
return !getRecipientKeyIds().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getDecryptionKeyId() {
|
public OpenPgpV4Fingerprint getDecryptionFingerprint() {
|
||||||
return decryptionKeyId;
|
return decryptionFingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SymmetricKeyAlgorithm getSymmetricKeyAlgorithm() {
|
public SymmetricKeyAlgorithm getSymmetricKeyAlgorithm() {
|
||||||
|
@ -75,26 +78,26 @@ public class PainlessResult {
|
||||||
return integrityProtected;
|
return integrityProtected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Long> getAllSignatureKeyIds() {
|
public Set<Long> getAllSignatureKeyFingerprints() {
|
||||||
return signatureKeyIds;
|
return unverifiedSignatureKeyIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSigned() {
|
public boolean isSigned() {
|
||||||
return !signatureKeyIds.isEmpty();
|
return !unverifiedSignatureKeyIds.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Long> getVerifiedSignatureKeyIds() {
|
public Set<OpenPgpV4Fingerprint> getVerifiedSignaturesFingerprints() {
|
||||||
return verifiedSignatureKeyIds;
|
return verifiedSignaturesFingerprints;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVerified() {
|
public boolean isVerified() {
|
||||||
return !verifiedSignatureKeyIds.isEmpty();
|
return !verifiedSignaturesFingerprints.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsVerifiedSignatureFrom(PGPPublicKeyRing publicKeys) {
|
public boolean containsVerifiedSignatureFrom(PGPPublicKeyRing publicKeys) throws PGPException {
|
||||||
for (PGPPublicKey key : publicKeys) {
|
for (PGPPublicKey key : publicKeys) {
|
||||||
long id = key.getKeyID();
|
OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(key);
|
||||||
if (verifiedSignatureKeyIds.contains(id)) {
|
if (verifiedSignaturesFingerprints.contains(fingerprint)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,21 +110,21 @@ public class PainlessResult {
|
||||||
|
|
||||||
static class Builder {
|
static class Builder {
|
||||||
|
|
||||||
private final Set<Long> recipientKeyIds = new HashSet<>();
|
private final Set<Long> recipientFingerprints = new HashSet<>();
|
||||||
private Long decryptionKeyId;
|
private OpenPgpV4Fingerprint decryptionFingerprint;
|
||||||
|
private final Set<Long> unverifiedSignatureKeyIds = new HashSet<>();
|
||||||
|
private final Set<OpenPgpV4Fingerprint> verifiedSignatureFingerprints = new HashSet<>();
|
||||||
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.NULL;
|
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.NULL;
|
||||||
private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
|
private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
|
||||||
private boolean integrityProtected = false;
|
private boolean integrityProtected = false;
|
||||||
private final Set<Long> signatureKeyIds = new HashSet<>();
|
|
||||||
private final Set<Long> verifiedSignatureKeyIds = new HashSet<>();
|
|
||||||
|
|
||||||
public Builder addRecipientKeyId(long id) {
|
public Builder addRecipientKeyId(Long keyId) {
|
||||||
this.recipientKeyIds.add(id);
|
this.recipientFingerprints.add(keyId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setDecryptionKeyId(long id) {
|
public Builder setDecryptionFingerprint(OpenPgpV4Fingerprint fingerprint) {
|
||||||
this.decryptionKeyId = id;
|
this.decryptionFingerprint = fingerprint;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,13 +133,13 @@ public class PainlessResult {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addSignatureKeyId(long id) {
|
public Builder addUnverifiedSignatureKeyId(Long keyId) {
|
||||||
this.signatureKeyIds.add(id);
|
this.unverifiedSignatureKeyIds.add(keyId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addVerifiedSignatureKeyId(long id) {
|
public Builder addVerifiedSignatureFingerprint(OpenPgpV4Fingerprint fingerprint) {
|
||||||
this.verifiedSignatureKeyIds.add(id);
|
this.verifiedSignatureFingerprints.add(fingerprint);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +154,7 @@ public class PainlessResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PainlessResult build() {
|
public PainlessResult build() {
|
||||||
return new PainlessResult(recipientKeyIds, decryptionKeyId, symmetricKeyAlgorithm, compressionAlgorithm, integrityProtected, signatureKeyIds, verifiedSignatureKeyIds);
|
return new PainlessResult(recipientFingerprints, decryptionFingerprint, symmetricKeyAlgorithm, compressionAlgorithm, integrityProtected, unverifiedSignatureKeyIds, verifiedSignatureFingerprints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.bouncycastle.openpgp.PGPObjectFactory;
|
||||||
import org.bouncycastle.openpgp.PGPOnePassSignature;
|
import org.bouncycastle.openpgp.PGPOnePassSignature;
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.bouncycastle.openpgp.PGPSignatureList;
|
import org.bouncycastle.openpgp.PGPSignatureList;
|
||||||
|
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
public class SignatureVerifyingInputStream extends FilterInputStream {
|
public class SignatureVerifyingInputStream extends FilterInputStream {
|
||||||
|
|
||||||
|
@ -35,14 +36,14 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
|
||||||
private static final Level LEVEL = Level.INFO;
|
private static final Level LEVEL = Level.INFO;
|
||||||
|
|
||||||
private final PGPObjectFactory objectFactory;
|
private final PGPObjectFactory objectFactory;
|
||||||
private final Map<Long, PGPOnePassSignature> onePassSignatures;
|
private final Map<OpenPgpV4Fingerprint, PGPOnePassSignature> onePassSignatures;
|
||||||
private final PainlessResult.Builder resultBuilder;
|
private final PainlessResult.Builder resultBuilder;
|
||||||
|
|
||||||
private boolean validated = false;
|
private boolean validated = false;
|
||||||
|
|
||||||
protected SignatureVerifyingInputStream(InputStream inputStream,
|
protected SignatureVerifyingInputStream(InputStream inputStream,
|
||||||
PGPObjectFactory objectFactory,
|
PGPObjectFactory objectFactory,
|
||||||
Map<Long, PGPOnePassSignature> onePassSignatures,
|
Map<OpenPgpV4Fingerprint, PGPOnePassSignature> onePassSignatures,
|
||||||
PainlessResult.Builder resultBuilder) {
|
PainlessResult.Builder resultBuilder) {
|
||||||
super(inputStream);
|
super(inputStream);
|
||||||
this.objectFactory = objectFactory;
|
this.objectFactory = objectFactory;
|
||||||
|
@ -94,16 +95,25 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PGPSignature signature : signatureList) {
|
for (PGPSignature signature : signatureList) {
|
||||||
PGPOnePassSignature onePassSignature = onePassSignatures.get(signature.getKeyID());
|
OpenPgpV4Fingerprint fingerprint = null;
|
||||||
if (onePassSignature == null) {
|
for (OpenPgpV4Fingerprint f : onePassSignatures.keySet()) {
|
||||||
|
if (f.getKeyId() == signature.getKeyID()) {
|
||||||
|
fingerprint = f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPOnePassSignature onePassSignature;
|
||||||
|
if (fingerprint == null || (onePassSignature = onePassSignatures.get(fingerprint)) == null) {
|
||||||
LOGGER.log(LEVEL, "Found Signature without respective OnePassSignature packet -> skip");
|
LOGGER.log(LEVEL, "Found Signature without respective OnePassSignature packet -> skip");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!onePassSignature.verify(signature)) {
|
if (!onePassSignature.verify(signature)) {
|
||||||
throw new SignatureException("Bad Signature of key " + signature.getKeyID());
|
throw new SignatureException("Bad Signature of key " + signature.getKeyID());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(LEVEL, "Verified signature of key " + Long.toHexString(signature.getKeyID()));
|
LOGGER.log(LEVEL, "Verified signature of key " + Long.toHexString(signature.getKeyID()));
|
||||||
resultBuilder.addVerifiedSignatureKeyId(signature.getKeyID());
|
resultBuilder.addVerifiedSignatureFingerprint(fingerprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (PGPException | SignatureException e) {
|
} catch (PGPException | SignatureException e) {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/**
|
/*
|
||||||
*
|
|
||||||
* Copyright 2018 Paul Schaub.
|
* Copyright 2018 Paul Schaub.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -16,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.pgpainless.pgpainless.key;
|
package org.pgpainless.pgpainless.key;
|
||||||
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -93,7 +92,12 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
|
||||||
* @return key id
|
* @return key id
|
||||||
*/
|
*/
|
||||||
public long getKeyId() {
|
public long getKeyId() {
|
||||||
byte[] bytes = DatatypeConverter.parseHexBinary(this.toString());
|
|
||||||
|
byte[] bytes = new BigInteger(toString(), 16).toByteArray();
|
||||||
|
if (bytes.length != toString().length() / 2) {
|
||||||
|
bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] lower8Bytes = Arrays.copyOfRange(bytes, 12, 20);
|
byte[] lower8Bytes = Arrays.copyOfRange(bytes, 12, 20);
|
||||||
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
|
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
|
||||||
byteBuffer.put(lower8Bytes);
|
byteBuffer.put(lower8Bytes);
|
||||||
|
|
|
@ -15,14 +15,19 @@
|
||||||
*/
|
*/
|
||||||
package org.pgpainless.pgpainless.key.collection;
|
package org.pgpainless.pgpainless.key.collection;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
|
import org.pgpainless.pgpainless.PGPainless;
|
||||||
|
|
||||||
public class KeyRingCollection {
|
public class KeyRingCollection {
|
||||||
|
|
||||||
|
@ -36,6 +41,20 @@ public class KeyRingCollection {
|
||||||
this.secretKeys = secretKeyRings;
|
this.secretKeys = secretKeyRings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyRingCollection(File pubRingFile, File secRingFile) throws IOException, PGPException {
|
||||||
|
if (pubRingFile != null) {
|
||||||
|
InputStream pubRingIn = new FileInputStream(pubRingFile);
|
||||||
|
this.publicKeys = PGPainless.readKeyRing().publicKeyRingCollection(pubRingIn);
|
||||||
|
pubRingIn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secRingFile != null) {
|
||||||
|
InputStream secRingIn = new FileInputStream(secRingFile);
|
||||||
|
this.secretKeys = PGPainless.readKeyRing().secretKeyRingCollection(secRingIn);
|
||||||
|
secRingIn.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public KeyRingCollection(PGPPublicKeyRingCollection publicKeyRings) {
|
public KeyRingCollection(PGPPublicKeyRingCollection publicKeyRings) {
|
||||||
this(publicKeyRings, null);
|
this(publicKeyRings, null);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +64,12 @@ public class KeyRingCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importPublicKeys(PGPPublicKeyRingCollection publicKeyRings) {
|
public void importPublicKeys(PGPPublicKeyRingCollection publicKeyRings) {
|
||||||
for (PGPPublicKeyRing keyRing : Objects.requireNonNull(publicKeyRings)) {
|
if (this.publicKeys == null) {
|
||||||
|
this.publicKeys = publicKeyRings;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PGPPublicKeyRing keyRing : publicKeyRings) {
|
||||||
try {
|
try {
|
||||||
this.publicKeys = PGPPublicKeyRingCollection.addPublicKeyRing(this.publicKeys, keyRing);
|
this.publicKeys = PGPPublicKeyRingCollection.addPublicKeyRing(this.publicKeys, keyRing);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
@ -57,7 +81,12 @@ public class KeyRingCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importSecretKeys(PGPSecretKeyRingCollection secretKeyRings) {
|
public void importSecretKeys(PGPSecretKeyRingCollection secretKeyRings) {
|
||||||
for (PGPSecretKeyRing keyRing : Objects.requireNonNull(secretKeyRings)) {
|
if (this.secretKeys == null) {
|
||||||
|
this.secretKeys = secretKeyRings;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PGPSecretKeyRing keyRing : secretKeyRings) {
|
||||||
try {
|
try {
|
||||||
this.secretKeys = PGPSecretKeyRingCollection.addSecretKeyRing(this.secretKeys, keyRing);
|
this.secretKeys = PGPSecretKeyRingCollection.addSecretKeyRing(this.secretKeys, keyRing);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -43,13 +42,13 @@ import org.pgpainless.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.pgpainless.decryption_verification.DecryptionStream;
|
import org.pgpainless.pgpainless.decryption_verification.DecryptionStream;
|
||||||
import org.pgpainless.pgpainless.decryption_verification.PainlessResult;
|
import org.pgpainless.pgpainless.decryption_verification.PainlessResult;
|
||||||
import org.pgpainless.pgpainless.encryption_signing.EncryptionStream;
|
import org.pgpainless.pgpainless.encryption_signing.EncryptionStream;
|
||||||
import org.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
|
|
||||||
import org.pgpainless.pgpainless.key.protection.UnprotectedKeysProtector;
|
|
||||||
import org.pgpainless.pgpainless.key.generation.KeySpec;
|
import org.pgpainless.pgpainless.key.generation.KeySpec;
|
||||||
import org.pgpainless.pgpainless.key.generation.type.ElGamal_GENERAL;
|
import org.pgpainless.pgpainless.key.generation.type.ElGamal_GENERAL;
|
||||||
import org.pgpainless.pgpainless.key.generation.type.RSA_GENERAL;
|
import org.pgpainless.pgpainless.key.generation.type.RSA_GENERAL;
|
||||||
import org.pgpainless.pgpainless.key.generation.type.length.ElGamalLength;
|
import org.pgpainless.pgpainless.key.generation.type.length.ElGamalLength;
|
||||||
import org.pgpainless.pgpainless.key.generation.type.length.RsaLength;
|
import org.pgpainless.pgpainless.key.generation.type.length.RsaLength;
|
||||||
|
import org.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.pgpainless.key.protection.UnprotectedKeysProtector;
|
||||||
import org.pgpainless.pgpainless.util.BCUtil;
|
import org.pgpainless.pgpainless.util.BCUtil;
|
||||||
|
|
||||||
public class EncryptDecryptTest extends AbstractPGPainlessTest {
|
public class EncryptDecryptTest extends AbstractPGPainlessTest {
|
||||||
|
@ -142,8 +141,8 @@ public class EncryptDecryptTest extends AbstractPGPainlessTest {
|
||||||
|
|
||||||
PainlessResult encryptionResult = encryptor.getResult();
|
PainlessResult encryptionResult = encryptor.getResult();
|
||||||
|
|
||||||
assertFalse(encryptionResult.getAllSignatureKeyIds().isEmpty());
|
assertFalse(encryptionResult.getAllSignatureKeyFingerprints().isEmpty());
|
||||||
for (long keyId : encryptionResult.getAllSignatureKeyIds()) {
|
for (long keyId : encryptionResult.getAllSignatureKeyFingerprints()) {
|
||||||
assertTrue(BCUtil.keyRingContainsKeyWithId(sender, keyId));
|
assertTrue(BCUtil.keyRingContainsKeyWithId(sender, keyId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,8 +167,7 @@ public class EncryptDecryptTest extends AbstractPGPainlessTest {
|
||||||
DecryptionStream decryptor = PGPainless.createDecryptor()
|
DecryptionStream decryptor = PGPainless.createDecryptor()
|
||||||
.onInputStream(envelopeIn)
|
.onInputStream(envelopeIn)
|
||||||
.decryptWith(keyDecryptor, BCUtil.keyRingsToKeyRingCollection(recipient))
|
.decryptWith(keyDecryptor, BCUtil.keyRingsToKeyRingCollection(recipient))
|
||||||
.verifyWith(Collections.singleton(senderPub.getPublicKey().getKeyID()),
|
.verifyWith(BCUtil.keyRingsToKeyRingCollection(senderPub))
|
||||||
BCUtil.keyRingsToKeyRingCollection(senderPub))
|
|
||||||
.ignoreMissingPublicKeys()
|
.ignoreMissingPublicKeys()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.pgpainless;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
public class OpenPgpV4FingerprintTest {
|
||||||
|
|
||||||
|
@Test(expected = PGPException.class)
|
||||||
|
public void fpTooShort() throws PGPException {
|
||||||
|
String fp = "484f57414c495645"; // Asking Mark
|
||||||
|
new OpenPgpV4Fingerprint(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = PGPException.class)
|
||||||
|
public void invalidHexTest() throws PGPException {
|
||||||
|
String fp = "UNFORTUNATELYTHISISNOVALIDHEXADECIMALDOH";
|
||||||
|
new OpenPgpV4Fingerprint(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validFingerprintTest() throws PGPException {
|
||||||
|
String fp = "4A4F48414E4E53454E2049532041204E45524421";
|
||||||
|
OpenPgpV4Fingerprint finger = new OpenPgpV4Fingerprint(fp);
|
||||||
|
assertEquals(fp, finger.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsToUpperCaseTest() throws PGPException {
|
||||||
|
String fp = "444f4e5420552048415645204120484f4242593f";
|
||||||
|
OpenPgpV4Fingerprint finger = new OpenPgpV4Fingerprint(fp);
|
||||||
|
assertEquals("444F4E5420552048415645204120484F4242593F", finger.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void equalsOtherFingerprintTest() throws PGPException {
|
||||||
|
OpenPgpV4Fingerprint finger = new OpenPgpV4Fingerprint("5448452043414b452049532041204c4945212121");
|
||||||
|
assertEquals(finger, new OpenPgpV4Fingerprint("5448452043414B452049532041204C4945212121"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void keyIdTest() throws IOException, PGPException {
|
||||||
|
PGPPublicKey key = TestKeys.getJulietPublicKeyRing().getPublicKey();
|
||||||
|
long keyId = key.getKeyID();
|
||||||
|
|
||||||
|
OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(key);
|
||||||
|
assertEquals(keyId, fingerprint.getKeyId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,9 +57,7 @@ public class TestKeysTest extends AbstractPGPainlessTest {
|
||||||
DecryptionStream decryptor = PGPainless.createDecryptor()
|
DecryptionStream decryptor = PGPainless.createDecryptor()
|
||||||
.onInputStream(new ByteArrayInputStream(encryptedMessage.getBytes()))
|
.onInputStream(new ByteArrayInputStream(encryptedMessage.getBytes()))
|
||||||
.decryptWith(new UnprotectedKeysProtector(), new PGPSecretKeyRingCollection(Collections.singleton(juliet)))
|
.decryptWith(new UnprotectedKeysProtector(), new PGPSecretKeyRingCollection(Collections.singleton(juliet)))
|
||||||
.verifyWith(
|
.verifyWith(BCUtil.keyRingsToKeyRingCollection(BCUtil.publicKeyRingFromSecretKeyRing(juliet)))
|
||||||
Collections.singleton(juliet.getPublicKey().getKeyID()),
|
|
||||||
BCUtil.keyRingsToKeyRingCollection(BCUtil.publicKeyRingFromSecretKeyRing(juliet)))
|
|
||||||
.ignoreMissingPublicKeys()
|
.ignoreMissingPublicKeys()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue