Adjust to latest changes and add tests from test suite

This commit is contained in:
Paul Schaub 2025-01-09 14:05:15 +01:00
parent b77c8549b7
commit 994ba47b30
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
28 changed files with 272 additions and 57 deletions

View file

@ -23,6 +23,11 @@
<groupId>org.pgpainless</groupId> <groupId>org.pgpainless</groupId>
<artifactId>sop-java</artifactId> <artifactId>sop-java</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.pgpainless</groupId>
<artifactId>sop-java-testfixtures</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.bouncycastle</groupId> <groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId> <artifactId>bcprov-jdk18on</artifactId>
@ -47,6 +52,16 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<environmentVariables>
<test.implementation>org.pgpainless.bouncycastle.sop.BouncyCastleSOPInstanceFactory</test.implementation>
</environmentVariables>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -1,108 +1,139 @@
package org.pgpainless.bouncycastle.sop; package org.pgpainless.bouncycastle.sop;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.bc.BcOpenPGPApi;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.pgpainless.bouncycastle.sop.operation.*; import org.pgpainless.bouncycastle.sop.operation.BCArmor;
import org.pgpainless.bouncycastle.sop.operation.BCDearmor;
import org.pgpainless.bouncycastle.sop.operation.BCDecrypt;
import org.pgpainless.bouncycastle.sop.operation.BCDetachedSign;
import org.pgpainless.bouncycastle.sop.operation.BCDetachedVerify;
import org.pgpainless.bouncycastle.sop.operation.BCEncrypt;
import org.pgpainless.bouncycastle.sop.operation.BCExtractCert;
import org.pgpainless.bouncycastle.sop.operation.BCGenerateKey;
import org.pgpainless.bouncycastle.sop.operation.BCInlineSign;
import org.pgpainless.bouncycastle.sop.operation.BCInlineVerify;
import org.pgpainless.bouncycastle.sop.operation.BCListProfiles;
import org.pgpainless.bouncycastle.sop.operation.BCVersion;
import sop.SOP; import sop.SOP;
import sop.operation.*; import sop.exception.SOPGPException;
import sop.operation.Armor;
import sop.operation.ChangeKeyPassword;
import sop.operation.Dearmor;
import sop.operation.Decrypt;
import sop.operation.DetachedSign;
import sop.operation.DetachedVerify;
import sop.operation.Encrypt;
import sop.operation.ExtractCert;
import sop.operation.GenerateKey;
import sop.operation.InlineDetach;
import sop.operation.InlineSign;
import sop.operation.InlineVerify;
import sop.operation.ListProfiles;
import sop.operation.RevokeKey;
import sop.operation.Version;
import java.security.Security; import java.security.Security;
public class BouncyCastleSOP implements SOP { public class BouncyCastleSOP implements SOP {
private final OpenPGPApi api;
public BouncyCastleSOP() public BouncyCastleSOP()
{ {
Security.removeProvider("BC"); Security.removeProvider("BC");
Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new BouncyCastleProvider());
this.api = new BcOpenPGPApi();
} }
@NotNull @NotNull
@Override @Override
public Armor armor() { public Armor armor() {
return new BCArmor(); return new BCArmor(api);
} }
@NotNull @NotNull
@Override @Override
public GenerateKey generateKey() { public GenerateKey generateKey() {
return new BCGenerateKey(); return new BCGenerateKey(api);
} }
@NotNull @NotNull
@Override @Override
public ExtractCert extractCert() { public ExtractCert extractCert() {
return new BCExtractCert(); return new BCExtractCert(api);
} }
@NotNull @NotNull
@Override @Override
public DetachedSign detachedSign() { public DetachedSign detachedSign() {
return new BCDetachedSign(); return new BCDetachedSign(api);
} }
@NotNull @NotNull
@Override @Override
public InlineSign inlineSign() { public InlineSign inlineSign() {
return new BCInlineSign(); return new BCInlineSign(api);
} }
@NotNull @NotNull
@Override @Override
public InlineDetach inlineDetach() { public InlineDetach inlineDetach() {
return null; throw new SOPGPException.UnsupportedSubcommand("inline-detach is not implemented.");
} }
@NotNull @NotNull
@Override @Override
public Encrypt encrypt() { public Encrypt encrypt() {
return new BCEncrypt(); return new BCEncrypt(api);
} }
@NotNull @NotNull
@Override @Override
public Decrypt decrypt() { public Decrypt decrypt() {
return new BCDecrypt(); return new BCDecrypt(api);
} }
@NotNull @NotNull
@Override @Override
public Dearmor dearmor() { public Dearmor dearmor() {
return new BCDearmor(); return new BCDearmor(api);
} }
@NotNull @NotNull
@Override @Override
public ListProfiles listProfiles() { public ListProfiles listProfiles() {
return new BCListProfiles(); return new BCListProfiles(api);
} }
@NotNull @NotNull
@Override @Override
public RevokeKey revokeKey() { public RevokeKey revokeKey() {
return null; throw new SOPGPException.UnsupportedSubcommand("revoke-key is not implemented.");
} }
@NotNull @NotNull
@Override @Override
public ChangeKeyPassword changeKeyPassword() { public ChangeKeyPassword changeKeyPassword() {
return null; throw new SOPGPException.UnsupportedSubcommand("change-key-password is not implemented.");
} }
@NotNull @NotNull
@Override @Override
public Version version() { public Version version() {
return new BCVersion(); return new BCVersion(api);
} }
@NotNull @NotNull
@Override @Override
public DetachedVerify detachedVerify() { public DetachedVerify detachedVerify() {
return new BCDetachedVerify(); return new BCDetachedVerify(api);
} }
@NotNull @NotNull
@Override @Override
public InlineVerify inlineVerify() { public InlineVerify inlineVerify() {
return new BCInlineVerify(); return new BCInlineVerify(api);
} }
} }

View file

@ -2,18 +2,30 @@ package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.PGPSessionKey; import org.bouncycastle.openpgp.PGPSessionKey;
import org.bouncycastle.openpgp.PGPSignatureException; import org.bouncycastle.openpgp.PGPSignatureException;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream; import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream;
import org.bouncycastle.openpgp.api.OpenPGPSignature; import org.bouncycastle.openpgp.api.OpenPGPSignature;
import org.bouncycastle.openpgp.api.exception.MalformedPGPSignatureException;
import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.Hex;
import sop.SessionKey; import sop.SessionKey;
import sop.Verification; import sop.Verification;
import sop.exception.SOPGPException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
public abstract class AbstractBCOperation public abstract class AbstractBCOperation
{ {
protected final OpenPGPApi api;
protected AbstractBCOperation(OpenPGPApi api)
{
this.api = api;
}
protected SessionKey getSessionKey(OpenPGPMessageInputStream.Result result) protected SessionKey getSessionKey(OpenPGPMessageInputStream.Result result)
{ {
@ -35,8 +47,8 @@ public abstract class AbstractBCOperation
if (sig.isValid()) if (sig.isValid())
{ {
Verification verification = new Verification(sig.getCreationTime(), Verification verification = new Verification(sig.getCreationTime(),
Hex.toHexString(sig.getIssuer().getKeyIdentifier().getFingerprint()), Hex.toHexString(sig.getIssuer().getKeyIdentifier().getFingerprint()).toUpperCase(Locale.ROOT),
Hex.toHexString(sig.getIssuerCertificate().getFingerprint())); Hex.toHexString(sig.getIssuerCertificate().getFingerprint()).toUpperCase(Locale.ROOT));
verifications.add(verification); verifications.add(verification);
} }
} }
@ -47,4 +59,22 @@ public abstract class AbstractBCOperation
} }
return verifications; return verifications;
} }
protected OpenPGPCertificate parseCertificate(InputStream inputStream)
{
try {
return api.readKeyOrCertificate().parseCertificate(inputStream);
} catch (IOException e) {
throw new SOPGPException.BadData(e);
}
}
protected OpenPGPKey parseKey(InputStream inputStream)
{
try {
return api.readKeyOrCertificate().parseKey(inputStream);
} catch (IOException e) {
throw new SOPGPException.BadData(e);
}
}
} }

View file

@ -1,6 +1,7 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import sop.Ready; import sop.Ready;
@ -15,6 +16,10 @@ public class BCArmor
extends AbstractBCOperation extends AbstractBCOperation
implements Armor { implements Armor {
public BCArmor(OpenPGPApi api) {
super(api);
}
@NotNull @NotNull
@Override @Override
public Ready data(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException { public Ready data(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException {

View file

@ -1,6 +1,7 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.bcpg.ArmoredInputStream;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import sop.Ready; import sop.Ready;
@ -15,6 +16,10 @@ public class BCDearmor
extends AbstractBCOperation extends AbstractBCOperation
implements Dearmor { implements Dearmor {
public BCDearmor(OpenPGPApi api) {
super(api);
}
@NotNull @NotNull
@Override @Override
public Ready data(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException { public Ready data(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException {

View file

@ -1,8 +1,8 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.*; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.PGPSessionKey;
import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream; import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream;
import org.bouncycastle.openpgp.api.OpenPGPMessageProcessor; import org.bouncycastle.openpgp.api.OpenPGPMessageProcessor;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
@ -16,18 +16,20 @@ import sop.operation.Decrypt;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
public class BCDecrypt public class BCDecrypt
extends AbstractBCOperation extends AbstractBCOperation
implements Decrypt { implements Decrypt {
private final OpenPGPMessageProcessor processor;
private char[] keyPassword; private char[] keyPassword;
private final OpenPGPMessageProcessor processor = new OpenPGPMessageProcessor(); public BCDecrypt(OpenPGPApi api) {
super(api);
this.processor = api.decryptAndOrVerifyMessage();
}
@NotNull @NotNull
@Override @Override
@ -67,8 +69,7 @@ public class BCDecrypt
@NotNull @NotNull
@Override @Override
public Decrypt verifyWithCert(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException { public Decrypt verifyWithCert(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
OpenPGPCertificate cert = OpenPGPCertificate.fromInputStream(inputStream); processor.addVerificationCertificate(parseCertificate(inputStream));
processor.addVerificationCertificate(cert);
return this; return this;
} }
@ -89,8 +90,7 @@ public class BCDecrypt
@NotNull @NotNull
@Override @Override
public Decrypt withKey(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException { public Decrypt withKey(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
OpenPGPKey key = OpenPGPKey.fromInputStream(inputStream); processor.addDecryptionKey(parseKey(inputStream), keyPassword);
processor.addDecryptionKey(key, keyPassword);
return this; return this;
} }

View file

@ -3,8 +3,8 @@ package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPDetachedSignatureGenerator; import org.bouncycastle.openpgp.api.OpenPGPDetachedSignatureGenerator;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPSignature; import org.bouncycastle.openpgp.api.OpenPGPSignature;
import org.bouncycastle.openpgp.api.exception.InvalidSigningKeyException; import org.bouncycastle.openpgp.api.exception.InvalidSigningKeyException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -24,10 +24,15 @@ public class BCDetachedSign
extends AbstractBCOperation extends AbstractBCOperation
implements DetachedSign { implements DetachedSign {
private final OpenPGPDetachedSignatureGenerator sigGen = new OpenPGPDetachedSignatureGenerator(); private final OpenPGPDetachedSignatureGenerator sigGen;
private boolean armored = true; private boolean armored = true;
private char[] keyPassword = null; private char[] keyPassword = null;
public BCDetachedSign(OpenPGPApi api) {
super(api);
sigGen = api.createDetachedSignature();
}
@NotNull @NotNull
@Override @Override
public ReadyWithResult<SigningResult> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText { public ReadyWithResult<SigningResult> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
@ -97,7 +102,7 @@ public class BCDetachedSign
public DetachedSign key(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException { public DetachedSign key(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
try try
{ {
sigGen.addSigningKey(OpenPGPKey.fromInputStream(inputStream), keyPassword); sigGen.addSigningKey(parseKey(inputStream), keyPassword);
} }
catch (InvalidSigningKeyException e) catch (InvalidSigningKeyException e)
{ {

View file

@ -1,6 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPDetachedSignatureProcessor; import org.bouncycastle.openpgp.api.OpenPGPDetachedSignatureProcessor;
import org.bouncycastle.openpgp.api.OpenPGPSignature; import org.bouncycastle.openpgp.api.OpenPGPSignature;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -19,10 +19,12 @@ public class BCDetachedVerify
implements DetachedVerify implements DetachedVerify
{ {
OpenPGPDetachedSignatureProcessor processor = new OpenPGPDetachedSignatureProcessor(); private final OpenPGPDetachedSignatureProcessor processor;
public BCDetachedVerify() public BCDetachedVerify(OpenPGPApi api)
{ {
super(api);
this.processor = api.verifyDetachedSignature();
processor.setExceptionCallback(e -> System.err.println(e.getMessage())); processor.setExceptionCallback(e -> System.err.println(e.getMessage()));
} }
@ -47,14 +49,14 @@ public class BCDetachedVerify
@Override @Override
public DetachedVerify cert(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException { public DetachedVerify cert(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException {
processor.addVerificationCertificate(OpenPGPCertificate.fromInputStream(inputStream)); processor.addVerificationCertificate(parseCertificate(inputStream));
return this; return this;
} }
@NotNull @NotNull
@Override @Override
public List<Verification> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData { public List<Verification> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData {
List<OpenPGPSignature.OpenPGPDocumentSignature> signatures = processor.verify(inputStream); List<OpenPGPSignature.OpenPGPDocumentSignature> signatures = processor.process(inputStream);
List<Verification> verifications = getVerifications(signatures); List<Verification> verifications = getVerifications(signatures);
if (verifications.isEmpty()) if (verifications.isEmpty())

View file

@ -1,10 +1,10 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator; import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator;
import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream; import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream;
import org.bouncycastle.openpgp.api.exception.InvalidEncryptionKeyException;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import sop.EncryptionResult; import sop.EncryptionResult;
@ -21,13 +21,12 @@ import java.io.OutputStream;
public class BCEncrypt public class BCEncrypt
extends AbstractBCOperation extends AbstractBCOperation
implements Encrypt { implements Encrypt {
private final OpenPGPMessageGenerator mGen; private final OpenPGPMessageGenerator mGen;
private char[] keyPassword; private char[] keyPassword;
public BCEncrypt() public BCEncrypt(OpenPGPApi api) {
{ super(api);
this.mGen = new OpenPGPMessageGenerator(); this.mGen = api.signAndOrEncryptMessage();
} }
@NotNull @NotNull
@ -47,8 +46,7 @@ public class BCEncrypt
@NotNull @NotNull
@Override @Override
public Encrypt signWith(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException { public Encrypt signWith(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
OpenPGPKey key = OpenPGPKey.fromInputStream(inputStream); mGen.addSigningKey(parseKey(inputStream), k -> keyPassword);
mGen.addSigningKey(key, k -> keyPassword);
return this; return this;
} }
@ -69,7 +67,11 @@ public class BCEncrypt
@NotNull @NotNull
@Override @Override
public Encrypt withCert(@NotNull InputStream inputStream) throws SOPGPException.CertCannotEncrypt, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException { public Encrypt withCert(@NotNull InputStream inputStream) throws SOPGPException.CertCannotEncrypt, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
mGen.addEncryptionCertificate(OpenPGPCertificate.fromInputStream(inputStream)); try {
mGen.addEncryptionCertificate(parseCertificate(inputStream));
} catch (InvalidEncryptionKeyException e) {
throw new SOPGPException.CertCannotEncrypt("Certificate cannot encrypt", e);
}
return this; return this;
} }

View file

@ -1,7 +1,12 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.*; import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; import org.bouncycastle.openpgp.bc.BcPGPObjectFactory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import sop.Ready; import sop.Ready;
@ -21,6 +26,10 @@ public class BCExtractCert
private boolean armor = true; private boolean armor = true;
public BCExtractCert(OpenPGPApi api) {
super(api);
}
@NotNull @NotNull
@Override @Override
public Ready key(@NotNull InputStream inputStream) throws IOException, SOPGPException.BadData { public Ready key(@NotNull InputStream inputStream) throws IOException, SOPGPException.BadData {

View file

@ -1,9 +1,9 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPV6KeyGenerator; import org.bouncycastle.openpgp.api.OpenPGPV6KeyGenerator;
import org.bouncycastle.openpgp.api.bc.BcOpenPGPV6KeyGenerator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import sop.Ready; import sop.Ready;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
@ -23,6 +23,10 @@ public class BCGenerateKey
private String userId; private String userId;
private char[] passphrase; private char[] passphrase;
public BCGenerateKey(OpenPGPApi api) {
super(api);
}
@NotNull @NotNull
@Override @Override
public Ready generate() throws SOPGPException.MissingArg, SOPGPException.UnsupportedAsymmetricAlgo, IOException { public Ready generate() throws SOPGPException.MissingArg, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
@ -33,7 +37,7 @@ public class BCGenerateKey
{ {
OpenPGPV6KeyGenerator generator = null; OpenPGPV6KeyGenerator generator = null;
try { try {
generator = new BcOpenPGPV6KeyGenerator(new Date()); generator = api.generateKey(new Date());
} catch (PGPException e) { } catch (PGPException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -1,7 +1,7 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator; import org.bouncycastle.openpgp.api.OpenPGPMessageGenerator;
import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream; import org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
@ -20,9 +20,14 @@ public class BCInlineSign
implements InlineSign implements InlineSign
{ {
private final OpenPGPMessageGenerator mGen = new OpenPGPMessageGenerator(); private final OpenPGPMessageGenerator mGen;
private char[] keyPassword; private char[] keyPassword;
public BCInlineSign(OpenPGPApi api) {
super(api);
this.mGen = api.signAndOrEncryptMessage();
}
@NotNull @NotNull
@Override @Override
public Ready data(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText { public Ready data(@NotNull InputStream inputStream) throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
@ -54,7 +59,7 @@ public class BCInlineSign
@Override @Override
public InlineSign key(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException { public InlineSign key(@NotNull InputStream inputStream) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo, IOException {
mGen.addSigningKey(OpenPGPKey.fromInputStream(inputStream), k -> keyPassword); mGen.addSigningKey(api.readKeyOrCertificate().parseKey(inputStream), k -> keyPassword);
return this; return this;
} }

View file

@ -1,7 +1,7 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream; import org.bouncycastle.openpgp.api.OpenPGPMessageInputStream;
import org.bouncycastle.openpgp.api.OpenPGPMessageProcessor; import org.bouncycastle.openpgp.api.OpenPGPMessageProcessor;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
@ -21,7 +21,12 @@ public class BCInlineVerify
extends AbstractBCOperation extends AbstractBCOperation
implements InlineVerify { implements InlineVerify {
private final OpenPGPMessageProcessor processor = new OpenPGPMessageProcessor(); private final OpenPGPMessageProcessor processor;
public BCInlineVerify(OpenPGPApi api) {
super(api);
this.processor = api.decryptAndOrVerifyMessage();
}
@NotNull @NotNull
@Override @Override
@ -61,7 +66,7 @@ public class BCInlineVerify
@Override @Override
public InlineVerify cert(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException { public InlineVerify cert(@NotNull InputStream inputStream) throws SOPGPException.BadData, IOException {
processor.addVerificationCertificate(OpenPGPCertificate.fromInputStream(inputStream)); processor.addVerificationCertificate(api.readKeyOrCertificate().parseCertificate(inputStream));
return this; return this;
} }
} }

View file

@ -1,5 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import sop.Profile; import sop.Profile;
import sop.operation.ListProfiles; import sop.operation.ListProfiles;
@ -10,6 +11,10 @@ public class BCListProfiles
extends AbstractBCOperation extends AbstractBCOperation
implements ListProfiles { implements ListProfiles {
public BCListProfiles(OpenPGPApi api) {
super(api);
}
@NotNull @NotNull
@Override @Override
public List<Profile> subcommand(@NotNull String s) { public List<Profile> subcommand(@NotNull String s) {

View file

@ -1,6 +1,7 @@
package org.pgpainless.bouncycastle.sop.operation; package org.pgpainless.bouncycastle.sop.operation;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.api.OpenPGPApi;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
@ -10,6 +11,10 @@ public class BCVersion
extends AbstractBCOperation extends AbstractBCOperation
implements Version { implements Version {
public BCVersion(OpenPGPApi api) {
super(api);
}
@NotNull @NotNull
@Override @Override
public String getBackendVersion() { public String getBackendVersion() {

View file

@ -0,0 +1,15 @@
package org.pgpainless.bouncycastle.sop;
import sop.SOP;
import sop.testsuite.SOPInstanceFactory;
import java.util.Collections;
import java.util.Map;
public class BouncyCastleSOPInstanceFactory extends SOPInstanceFactory {
@Override
public Map<String, SOP> provideSOPInstances() {
return Collections.singletonMap("bcsop", new BouncyCastleSOP());
}
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.ArmorDearmorTest;
public class BCSopArmorDearmorTest extends ArmorDearmorTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.ChangeKeyPasswordTest;
public class BCSopChangeKeyPasswordTest extends ChangeKeyPasswordTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.DecryptWithSessionKeyTest;
public class BCSopDecryptWithSessionKeyTest extends DecryptWithSessionKeyTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.DetachedSignDetachedVerifyTest;
public class BCSopDetachedSignDetachedVerifyTest extends DetachedSignDetachedVerifyTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.EncryptDecryptTest;
public class BCSopEncryptDecryptTest extends EncryptDecryptTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.ExtractCertTest;
public class BCSopExtractCertTest extends ExtractCertTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.GenerateKeyTest;
public class BCSopGenerateKeyTest extends GenerateKeyTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.InlineSignInlineDetachDetachedVerifyTest;
public class BCSopInlineSignInlineDetachDetachedVerifyTest extends InlineSignInlineDetachDetachedVerifyTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.InlineSignInlineVerifyTest;
public class BCSopInlineSignInlineVerifyTest extends InlineSignInlineVerifyTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.RevokeKeyTest;
public class BCSopRevokeKeyTest extends RevokeKeyTest {
}

View file

@ -0,0 +1,6 @@
package org.pgpainless.bouncycastle.sop.operation;
import sop.testsuite.operation.VersionTest;
public class BCSopVersionTest extends VersionTest {
}

View file

@ -55,6 +55,12 @@
<artifactId>sop-java-picocli</artifactId> <artifactId>sop-java-picocli</artifactId>
<version>10.0.3-SNAPSHOT</version> <version>10.0.3-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.pgpainless</groupId>
<artifactId>sop-java-testfixtures</artifactId>
<version>10.0.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>