mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-15 17:02:06 +01:00
Fix more tests
This commit is contained in:
parent
2a4bc03555
commit
4c6edc067b
2 changed files with 59 additions and 18 deletions
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.pgpainless.decryption_verification;
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -37,7 +36,6 @@ import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||||
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
|
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
|
||||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||||
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
||||||
import org.bouncycastle.util.io.Streams;
|
|
||||||
import org.bouncycastle.util.io.TeeInputStream;
|
import org.bouncycastle.util.io.TeeInputStream;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
|
@ -210,6 +208,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
case standard:
|
case standard:
|
||||||
// tee out packet bytes for signature verification
|
// tee out packet bytes for signature verification
|
||||||
packetInputStream = new TeeBCPGInputStream(BCPGInputStream.wrap(inputStream), this.signatures);
|
packetInputStream = new TeeBCPGInputStream(BCPGInputStream.wrap(inputStream), this.signatures);
|
||||||
|
@ -217,20 +216,22 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
// *omnomnom*
|
// *omnomnom*
|
||||||
consumePackets();
|
consumePackets();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cleartext_signed:
|
case cleartext_signed:
|
||||||
|
resultBuilder.setCleartextSigned();
|
||||||
MultiPassStrategy multiPassStrategy = options.getMultiPassStrategy();
|
MultiPassStrategy multiPassStrategy = options.getMultiPassStrategy();
|
||||||
PGPSignatureList detachedSignatures = ClearsignedMessageUtil
|
PGPSignatureList detachedSignatures = ClearsignedMessageUtil
|
||||||
.detachSignaturesFromInbandClearsignedMessage(
|
.detachSignaturesFromInbandClearsignedMessage(
|
||||||
inputStream, multiPassStrategy.getMessageOutputStream());
|
inputStream, multiPassStrategy.getMessageOutputStream());
|
||||||
|
|
||||||
for (PGPSignature signature : detachedSignatures) {
|
for (PGPSignature signature : detachedSignatures) {
|
||||||
options.addVerificationOfDetachedSignature(signature);
|
signatures.addDetachedSignature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
options.forceNonOpenPgpData();
|
options.forceNonOpenPgpData();
|
||||||
packetInputStream = null;
|
|
||||||
nestedInputStream = new TeeInputStream(multiPassStrategy.getMessageInputStream(), this.signatures);
|
nestedInputStream = new TeeInputStream(multiPassStrategy.getMessageInputStream(), this.signatures);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case non_openpgp:
|
case non_openpgp:
|
||||||
packetInputStream = null;
|
packetInputStream = null;
|
||||||
nestedInputStream = new TeeInputStream(inputStream, this.signatures);
|
nestedInputStream = new TeeInputStream(inputStream, this.signatures);
|
||||||
|
@ -348,14 +349,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
metadata.depth + 1);
|
metadata.depth + 1);
|
||||||
LOGGER.debug("Compressed Data Packet (" + compressionLayer.algorithm + ") at depth " + metadata.depth + " encountered");
|
LOGGER.debug("Compressed Data Packet (" + compressionLayer.algorithm + ") at depth " + metadata.depth + " encountered");
|
||||||
InputStream decompressed = compressedData.getDataStream();
|
InputStream decompressed = compressedData.getDataStream();
|
||||||
nestedInputStream = new OpenPgpMessageInputStream(buffer(decompressed), options, compressionLayer, policy);
|
nestedInputStream = new OpenPgpMessageInputStream(decompressed, options, compressionLayer, policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processOnePassSignature() throws PGPException, IOException {
|
private void processOnePassSignature() throws PGPException, IOException {
|
||||||
syntaxVerifier.next(InputAlphabet.OnePassSignature);
|
syntaxVerifier.next(InputAlphabet.OnePassSignature);
|
||||||
PGPOnePassSignature onePassSignature = packetInputStream.readOnePassSignature();
|
PGPOnePassSignature onePassSignature = packetInputStream.readOnePassSignature();
|
||||||
LOGGER.debug("One-Pass-Signature Packet by key " + KeyIdUtil.formatKeyId(onePassSignature.getKeyID()) +
|
LOGGER.debug("One-Pass-Signature Packet by key " + KeyIdUtil.formatKeyId(onePassSignature.getKeyID()) +
|
||||||
"at depth " + metadata.depth + " encountered");
|
" at depth " + metadata.depth + " encountered");
|
||||||
signatures.addOnePassSignature(onePassSignature);
|
signatures.addOnePassSignature(onePassSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +435,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
InputStream decrypted = skesk.getDataStream(decryptorFactory);
|
InputStream decrypted = skesk.getDataStream(decryptorFactory);
|
||||||
encryptedData.sessionKey = sessionKey;
|
encryptedData.sessionKey = sessionKey;
|
||||||
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options);
|
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options);
|
||||||
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
|
nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy);
|
||||||
LOGGER.debug("Successfully decrypted data with provided session key");
|
LOGGER.debug("Successfully decrypted data with provided session key");
|
||||||
return true;
|
return true;
|
||||||
} else if (esk instanceof PGPPublicKeyEncryptedData) {
|
} else if (esk instanceof PGPPublicKeyEncryptedData) {
|
||||||
|
@ -442,7 +443,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
InputStream decrypted = pkesk.getDataStream(decryptorFactory);
|
InputStream decrypted = pkesk.getDataStream(decryptorFactory);
|
||||||
encryptedData.sessionKey = sessionKey;
|
encryptedData.sessionKey = sessionKey;
|
||||||
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options);
|
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options);
|
||||||
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
|
nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy);
|
||||||
LOGGER.debug("Successfully decrypted data with provided session key");
|
LOGGER.debug("Successfully decrypted data with provided session key");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -579,7 +580,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
encryptedData.sessionKey = sessionKey;
|
encryptedData.sessionKey = sessionKey;
|
||||||
LOGGER.debug("Successfully decrypted data with passphrase");
|
LOGGER.debug("Successfully decrypted data with passphrase");
|
||||||
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options);
|
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options);
|
||||||
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
|
nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy);
|
||||||
return true;
|
return true;
|
||||||
} catch (UnacceptableAlgorithmException e) {
|
} catch (UnacceptableAlgorithmException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -606,7 +607,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
|
|
||||||
LOGGER.debug("Successfully decrypted data with key " + decryptionKeyId);
|
LOGGER.debug("Successfully decrypted data with key " + decryptionKeyId);
|
||||||
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options);
|
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options);
|
||||||
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
|
nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy);
|
||||||
return true;
|
return true;
|
||||||
} catch (UnacceptableAlgorithmException e) {
|
} catch (UnacceptableAlgorithmException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -631,10 +632,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InputStream buffer(InputStream inputStream) {
|
|
||||||
return new BufferedInputStream(inputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Tuple<PGPSecretKeyRing, PGPSecretKey>> findPotentialDecryptionKeys(PGPPublicKeyEncryptedData pkesk) {
|
private List<Tuple<PGPSecretKeyRing, PGPSecretKey>> findPotentialDecryptionKeys(PGPPublicKeyEncryptedData pkesk) {
|
||||||
int algorithm = pkesk.getAlgorithm();
|
int algorithm = pkesk.getAlgorithm();
|
||||||
List<Tuple<PGPSecretKeyRing, PGPSecretKey>> decryptionKeyCandidates = new ArrayList<>();
|
List<Tuple<PGPSecretKeyRing, PGPSecretKey>> decryptionKeyCandidates = new ArrayList<>();
|
||||||
|
@ -665,7 +662,9 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
@Override
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
if (nestedInputStream == null) {
|
if (nestedInputStream == null) {
|
||||||
syntaxVerifier.assertValid();
|
if (packetInputStream != null) {
|
||||||
|
syntaxVerifier.assertValid();
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +698,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
@Override
|
@Override
|
||||||
public int read(@Nonnull byte[] b, int off, int len)
|
public int read(@Nonnull byte[] b, int off, int len)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
if (nestedInputStream == null) {
|
if (nestedInputStream == null) {
|
||||||
if (packetInputStream != null) {
|
if (packetInputStream != null) {
|
||||||
syntaxVerifier.assertValid();
|
syntaxVerifier.assertValid();
|
||||||
|
@ -768,6 +766,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
throw new IllegalStateException("Stream must be closed before access to metadata can be granted.");
|
throw new IllegalStateException("Stream must be closed before access to metadata can be granted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MessageMetadata((MessageMetadata.Message) metadata);
|
return new MessageMetadata((MessageMetadata.Message) metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,6 +856,9 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
final Stack<List<OnePassSignatureCheck>> opsUpdateStack;
|
final Stack<List<OnePassSignatureCheck>> opsUpdateStack;
|
||||||
List<OnePassSignatureCheck> literalOPS = new ArrayList<>();
|
List<OnePassSignatureCheck> literalOPS = new ArrayList<>();
|
||||||
final List<PGPSignature> correspondingSignatures;
|
final List<PGPSignature> correspondingSignatures;
|
||||||
|
final List<SignatureVerification.Failure> prependedSignaturesWithMissingCert = new ArrayList<>();
|
||||||
|
final List<SignatureVerification.Failure> inbandSignaturesWithMissingCert = new ArrayList<>();
|
||||||
|
final List<SignatureVerification.Failure> detachedSignaturesWithMissingCert = new ArrayList<>();
|
||||||
boolean isLiteral = true;
|
boolean isLiteral = true;
|
||||||
|
|
||||||
private Signatures(ConsumerOptions options) {
|
private Signatures(ConsumerOptions options) {
|
||||||
|
@ -876,15 +878,29 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
|
|
||||||
void addDetachedSignature(PGPSignature signature) {
|
void addDetachedSignature(PGPSignature signature) {
|
||||||
SignatureCheck check = initializeSignature(signature);
|
SignatureCheck check = initializeSignature(signature);
|
||||||
|
long keyId = SignatureUtils.determineIssuerKeyId(signature);
|
||||||
if (check != null) {
|
if (check != null) {
|
||||||
detachedSignatures.add(check);
|
detachedSignatures.add(check);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("No suitable certificate for verification of signature by key " + KeyIdUtil.formatKeyId(keyId) + " found.");
|
||||||
|
this.detachedSignaturesWithMissingCert.add(new SignatureVerification.Failure(
|
||||||
|
new SignatureVerification(signature, null),
|
||||||
|
new SignatureValidationException("Missing verification key")
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPrependedSignature(PGPSignature signature) {
|
void addPrependedSignature(PGPSignature signature) {
|
||||||
SignatureCheck check = initializeSignature(signature);
|
SignatureCheck check = initializeSignature(signature);
|
||||||
|
long keyId = SignatureUtils.determineIssuerKeyId(signature);
|
||||||
if (check != null) {
|
if (check != null) {
|
||||||
this.prependedSignatures.add(check);
|
this.prependedSignatures.add(check);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("No suitable certificate for verification of signature by key " + KeyIdUtil.formatKeyId(keyId) + " found.");
|
||||||
|
this.prependedSignaturesWithMissingCert.add(new SignatureVerification.Failure(
|
||||||
|
new SignatureVerification(signature, null),
|
||||||
|
new SignatureValidationException("Missing verification key")
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,11 +932,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCorrespondingOnePassSignature(PGPSignature signature, MessageMetadata.Layer layer, Policy policy) {
|
void addCorrespondingOnePassSignature(PGPSignature signature, MessageMetadata.Layer layer, Policy policy) {
|
||||||
|
boolean found = false;
|
||||||
|
long keyId = SignatureUtils.determineIssuerKeyId(signature);
|
||||||
for (int i = onePassSignatures.size() - 1; i >= 0; i--) {
|
for (int i = onePassSignatures.size() - 1; i >= 0; i--) {
|
||||||
OnePassSignatureCheck onePassSignature = onePassSignatures.get(i);
|
OnePassSignatureCheck onePassSignature = onePassSignatures.get(i);
|
||||||
if (onePassSignature.getOnePassSignature().getKeyID() != signature.getKeyID()) {
|
if (onePassSignature.getOnePassSignature().getKeyID() != keyId) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
found = true;
|
||||||
|
|
||||||
if (onePassSignature.getSignature() != null) {
|
if (onePassSignature.getSignature() != null) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -942,6 +961,13 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
LOGGER.debug("No suitable certificate for verification of signature by key " + KeyIdUtil.formatKeyId(keyId) + " found.");
|
||||||
|
inbandSignaturesWithMissingCert.add(new SignatureVerification.Failure(
|
||||||
|
new SignatureVerification(signature, null),
|
||||||
|
new SignatureValidationException("Missing verification key.")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterNesting() {
|
void enterNesting() {
|
||||||
|
@ -983,6 +1009,10 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.getMissingCertificateCallback() != null) {
|
||||||
|
return options.getMissingCertificateCallback().onMissingPublicKeyEncountered(keyId);
|
||||||
|
}
|
||||||
return null; // TODO: Missing cert for sig
|
return null; // TODO: Missing cert for sig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,6 +1096,18 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
layer.addRejectedPrependedSignature(new SignatureVerification.Failure(verification, e));
|
layer.addRejectedPrependedSignature(new SignatureVerification.Failure(verification, e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (SignatureVerification.Failure rejected : inbandSignaturesWithMissingCert) {
|
||||||
|
layer.addRejectedOnePassSignature(rejected);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SignatureVerification.Failure rejected : prependedSignaturesWithMissingCert) {
|
||||||
|
layer.addRejectedPrependedSignature(rejected);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SignatureVerification.Failure rejected : detachedSignaturesWithMissingCert) {
|
||||||
|
layer.addRejectedDetachedSignature(rejected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -98,7 +98,6 @@ public class TeeBCPGInputStream {
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
this.packetInputStream.close();
|
this.packetInputStream.close();
|
||||||
this.delayedTee.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DelayedTeeInputStreamInputStream extends InputStream {
|
public static class DelayedTeeInputStreamInputStream extends InputStream {
|
||||||
|
|
Loading…
Reference in a new issue