Working native image

This commit is contained in:
Paul Schaub 2024-12-12 19:22:46 +01:00
parent cc4870219a
commit 0123b0e5fe
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
12 changed files with 254 additions and 41 deletions

View file

@ -10,14 +10,25 @@
</parent> </parent>
<artifactId>bcsop-cli</artifactId> <artifactId>bcsop-cli</artifactId>
<packaging>jar</packaging>
<properties> <properties>
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<native.maven.plugin.version>0.10.4</native.maven.plugin.version>
<imageName>bcsop-cli-native</imageName>
<mainClass>org.pgpainless.BcSopCLI</mainClass>
<graal.version>21.0.0</graal.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>svm</artifactId>
<version>${graal.version}</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>org.pgpainless</groupId> <groupId>org.pgpainless</groupId>
<artifactId>bcsop</artifactId> <artifactId>bcsop</artifactId>
@ -43,11 +54,51 @@
<build> <build>
<plugins> <plugins>
<!-- Annotation Processor -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher -->
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>info.picocli</groupId>
<artifactId>picocli-codegen</artifactId>
<version>4.6.3</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- Compile -->
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<annotationProcessorPaths>
<path>
<groupId>info.picocli</groupId>
<artifactId>picocli-codegen</artifactId>
<version>4.6.3</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Aproject=${project.groupId}/${project.artifactId}</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
</plugin> </plugin>
-->
<!-- Assembly -->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
@ -58,7 +109,7 @@
</descriptorRefs> </descriptorRefs>
<archive> <archive>
<manifest> <manifest>
<mainClass>org.pgpainless.BcSopCLI</mainClass> <mainClass>${mainClass}</mainClass>
</manifest> </manifest>
</archive> </archive>
</configuration> </configuration>
@ -72,6 +123,144 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<!-- GraalVM -->
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>${graal.version}</version>
<configuration>
<imageName>${imageName}</imageName>
<mainClass>${mainClass}</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
<!-- Reflections -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>generateGraalReflectionConfig</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<mainClass>picocli.codegen.aot.graalvm.ReflectionConfigGenerator</mainClass>
<arguments>
<argument>--output=bcsop-cli/target/classes/META-INF/native-image/${project.groupId}/${project.artifactId}/reflect-config.json</argument>
<!--<argument>org.pgpainless.BcSopCLI</argument>-->
<argument>sop.cli.picocli.SopCLI</argument>
<!--
<argument>sop.cli.picocli.commands.ArmorCmd</argument>
<argument>sop.cli.picocli.commands.ChangeKeyPasswordCmd</argument>
<argument>sop.cli.picocli.commands.DearmorCmd</argument>
<argument>sop.cli.picocli.commands.DecryptCmd</argument>
<argument>sop.cli.picocli.commands.EncryptCmd</argument>
<argument>sop.cli.picocli.commands.ExtractCertCmd</argument>
<argument>sop.cli.picocli.commands.GenerateKeyCmd</argument>
<argument>sop.cli.picocli.commands.InlineDetachCmd</argument>
<argument>sop.cli.picocli.commands.InlineSignCmd</argument>
<argument>sop.cli.picocli.commands.InlineVerifyCmd</argument>
<argument>sop.cli.picocli.commands.ListProfilesCmd</argument>
<argument>sop.cli.picocli.commands.RevokeKeyCmd</argument>
<argument>sop.cli.picocli.commands.SignCmd</argument>
<argument>sop.cli.picocli.commands.VerifyCmd</argument>
<argument>sop.cli.picocli.commands.VersionCmd</argument>
-->
</arguments>
</configuration>
</execution>
<execution>
<id>generateGraalDynamicProxyConfig</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<mainClass>picocli.codegen.aot.graalvm.DynamicProxyConfigGenerator</mainClass>
<arguments>
<argument>--output=bcsop-cli/target/classes/META-INF/native-image/${project.groupId}/${project.artifactId}/proxy-config.json</argument>
<!--<argument>org.pgpainless.BcSopCLI</argument>-->
<argument>sop.cli.picocli.SopCLI</argument>
<!--
<argument>sop.cli.picocli.commands.ArmorCmd</argument>
<argument>sop.cli.picocli.commands.ChangeKeyPasswordCmd</argument>
<argument>sop.cli.picocli.commands.DearmorCmd</argument>
<argument>sop.cli.picocli.commands.DecryptCmd</argument>
<argument>sop.cli.picocli.commands.EncryptCmd</argument>
<argument>sop.cli.picocli.commands.ExtractCertCmd</argument>
<argument>sop.cli.picocli.commands.GenerateKeyCmd</argument>
<argument>sop.cli.picocli.commands.InlineDetachCmd</argument>
<argument>sop.cli.picocli.commands.InlineSignCmd</argument>
<argument>sop.cli.picocli.commands.InlineVerifyCmd</argument>
<argument>sop.cli.picocli.commands.ListProfilesCmd</argument>
<argument>sop.cli.picocli.commands.RevokeKeyCmd</argument>
<argument>sop.cli.picocli.commands.SignCmd</argument>
<argument>sop.cli.picocli.commands.VerifyCmd</argument>
<argument>sop.cli.picocli.commands.VersionCmd</argument>
-->
</arguments>
</configuration>
</execution>
<execution>
<id>generateGraalResourceConfig</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<mainClass>picocli.codegen.aot.graalvm.ResourceConfigGenerator</mainClass>
<arguments>
<argument>--output=bcsop-cli/target/classes/META-INF/native-image/${project.groupId}/${project.artifactId}/resource-config.json</argument>
<!--<argument>org.pgpainless.BcSopCLI</argument>-->
<argument>sop.cli.picocli.SopCLI</argument>
<!--
<argument>sop.cli.picocli.commands.ArmorCmd</argument>
<argument>sop.cli.picocli.commands.ChangeKeyPasswordCmd</argument>
<argument>sop.cli.picocli.commands.DearmorCmd</argument>
<argument>sop.cli.picocli.commands.DecryptCmd</argument>
<argument>sop.cli.picocli.commands.EncryptCmd</argument>
<argument>sop.cli.picocli.commands.ExtractCertCmd</argument>
<argument>sop.cli.picocli.commands.GenerateKeyCmd</argument>
<argument>sop.cli.picocli.commands.InlineDetachCmd</argument>
<argument>sop.cli.picocli.commands.InlineSignCmd</argument>
<argument>sop.cli.picocli.commands.InlineVerifyCmd</argument>
<argument>sop.cli.picocli.commands.ListProfilesCmd</argument>
<argument>sop.cli.picocli.commands.RevokeKeyCmd</argument>
<argument>sop.cli.picocli.commands.SignCmd</argument>
<argument>sop.cli.picocli.commands.VerifyCmd</argument>
<argument>sop.cli.picocli.commands.VersionCmd</argument>
-->
</arguments>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-codegen</artifactId>
<version>4.6.3</version>
<type>jar</type>
</dependency>
</dependencies>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View file

@ -1,14 +1,27 @@
package org.pgpainless; package org.pgpainless;
import org.pgpainless.bouncycastle.sop.BouncyCastleSOP; import org.pgpainless.bouncycastle.sop.BouncyCastleSOP;
import picocli.CommandLine;
import sop.cli.picocli.SOPExceptionExitCodeMapper;
import sop.cli.picocli.SOPExecutionExceptionHandler;
import sop.cli.picocli.SopCLI; import sop.cli.picocli.SopCLI;
public class BcSopCLI { public class BcSopCLI extends SopCLI {
public static void main(String[] args) { public static void main(String[] args) {
SopCLI.EXECUTABLE_NAME = "bc-sop"; SopCLI.EXECUTABLE_NAME = "bc-sop";
SopCLI.setSopInstance(new BouncyCastleSOP()); SopCLI.setSopInstance(new BouncyCastleSOP());
int exitCode = SopCLI.execute(args); System.exit(run(args));
System.exit(exitCode); }
public static int run(String[] args)
{
CommandLine cmd = new CommandLine(SopCLI.class);
cmd.getSubcommands().get("generate-completion").getCommandSpec().usageMessage().hidden(true);
cmd.setCommandName("bcsop");
cmd.setExecutionExceptionHandler(new SOPExecutionExceptionHandler());
cmd.setExitCodeExceptionMapper(new SOPExceptionExitCodeMapper());
cmd.setCaseInsensitiveEnumValuesAllowed(true);
return cmd.execute(args);
} }
} }

View file

@ -23,10 +23,10 @@ public abstract class AbstractBCOperation
return new SessionKey((byte) sessionKey.getAlgorithm(), sessionKey.getKey()); return new SessionKey((byte) sessionKey.getAlgorithm(), sessionKey.getKey());
} }
protected List<Verification> getVerifications(OpenPGPMessageInputStream.Result result) protected List<Verification> getVerifications(List<OpenPGPSignature.OpenPGPDocumentSignature> signatures)
{ {
List<Verification> verifications = new ArrayList<>(); List<Verification> verifications = new ArrayList<>();
for (OpenPGPSignature.OpenPGPDocumentSignature sig : result.getSignatures()) for (OpenPGPSignature.OpenPGPDocumentSignature sig : signatures)
{ {
if (sig.isValid()) if (sig.isValid())
{ {

View file

@ -4,7 +4,6 @@ import org.bouncycastle.bcpg.ArmoredOutputStream;
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;
import sop.enums.ArmorLabel;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import sop.operation.Armor; import sop.operation.Armor;
@ -30,10 +29,4 @@ public class BCArmor
} }
}; };
} }
@NotNull
@Override
public Armor label(@NotNull ArmorLabel armorLabel) throws SOPGPException.UnsupportedOption {
throw new SOPGPException.UnsupportedOption("Custom labels not supported.");
}
} }

View file

@ -26,8 +26,7 @@ public class BCDecrypt
private Date notBefore = new Date(Long.MAX_VALUE); // end of time private Date notBefore = new Date(Long.MAX_VALUE); // end of time
private Date notAfter = new Date(); // now private Date notAfter = new Date(); // now
private final List<PGPSecretKeyRing> encryptionKeys = new ArrayList<>(); private char[] keyPassword;
private final List<String> encryptionKeyPassphrases = new ArrayList<>();
private final OpenPGPMessageProcessor processor = new OpenPGPMessageProcessor(); private final OpenPGPMessageProcessor processor = new OpenPGPMessageProcessor();
@ -35,7 +34,7 @@ public class BCDecrypt
@NotNull @NotNull
@Override @Override
public ReadyWithResult<DecryptionResult> ciphertext(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt, SOPGPException.KeyIsProtected, IOException { public ReadyWithResult<DecryptionResult> ciphertext(@NotNull InputStream inputStream) throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt, SOPGPException.KeyIsProtected, IOException {
return new ReadyWithResult<DecryptionResult>() { return new ReadyWithResult<>() {
@Override @Override
public DecryptionResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException { public DecryptionResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
try { try {
@ -45,7 +44,7 @@ public class BCDecrypt
OpenPGPMessageInputStream.Result result = mIn.getResult(); OpenPGPMessageInputStream.Result result = mIn.getResult();
return new DecryptionResult( return new DecryptionResult(
getSessionKey(result), getSessionKey(result),
getVerifications(result)); getVerifications(result.getSignatures()));
} catch (PGPException e) { } catch (PGPException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -93,7 +92,7 @@ public class BCDecrypt
@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); OpenPGPKey key = OpenPGPKey.fromInputStream(inputStream);
processor.addDecryptionKey(key); processor.addDecryptionKey(key, keyPassword);
return this; return this;
} }
@ -101,7 +100,7 @@ public class BCDecrypt
@Override @Override
public Decrypt withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable { public Decrypt withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
String passphrase = new String(bytes); String passphrase = new String(bytes);
this.encryptionKeyPassphrases.add(passphrase); this.keyPassword = passphrase.toCharArray();
return this; return this;
} }
} }

View file

@ -26,6 +26,7 @@ public class BCDetachedSign
private final OpenPGPDetachedSignatureGenerator sigGen = new OpenPGPDetachedSignatureGenerator(); private final OpenPGPDetachedSignatureGenerator sigGen = new OpenPGPDetachedSignatureGenerator();
private boolean armored = true; private boolean armored = true;
private char[] keyPassword = null;
@NotNull @NotNull
@Override @Override
@ -96,7 +97,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), null); sigGen.addSigningKey(OpenPGPKey.fromInputStream(inputStream), keyPassword);
} }
catch (InvalidSigningKeyException e) catch (InvalidSigningKeyException e)
{ {
@ -111,6 +112,7 @@ public class BCDetachedSign
@Override @Override
public DetachedSign withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable { public DetachedSign withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
keyPassword = new String(bytes).toCharArray();
return this; return this;
} }
} }

View file

@ -56,16 +56,10 @@ public class BCDetachedVerify
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.verify(inputStream);
List<Verification> verifications = new ArrayList<>(); List<Verification> verifications = getVerifications(signatures);
for (OpenPGPSignature.OpenPGPDocumentSignature signature : signatures) if (verifications.isEmpty())
{ {
if (signature.isValidAt(signature.getCreationTime())) throw new SOPGPException.NoSignature();
{
verifications.add(new Verification(
signature.getCreationTime(),
Hex.toHexString(signature.getIssuer().getKeyIdentifier().getFingerprint()),
Hex.toHexString(signature.getIssuerCertificate().getFingerprint())));
}
} }
return verifications; return verifications;
} }

View file

@ -2,6 +2,7 @@ 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.OpenPGPCertificate;
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.util.io.Streams; import org.bouncycastle.util.io.Streams;
@ -22,6 +23,7 @@ public class BCEncrypt
implements Encrypt { implements Encrypt {
private final OpenPGPMessageGenerator mGen; private final OpenPGPMessageGenerator mGen;
private char[] keyPassword;
public BCEncrypt() public BCEncrypt()
{ {
@ -45,12 +47,15 @@ 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(key, k -> keyPassword);
return this; return this;
} }
@NotNull @NotNull
@Override @Override
public Encrypt withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption { public Encrypt withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
this.keyPassword = new String(bytes).toCharArray();
return this; return this;
} }

View file

@ -33,23 +33,33 @@ public class BCGenerateKey
public void writeTo(@NotNull OutputStream outputStream) throws IOException public void writeTo(@NotNull OutputStream outputStream) throws IOException
{ {
OpenPGPV6KeyGenerator generator = new BcOpenPGPV6KeyGenerator(new Date()); OpenPGPV6KeyGenerator generator = new BcOpenPGPV6KeyGenerator(new Date());
OpenPGPKey key;
try try
{ {
PGPSecretKeyRing keyRing = generator.ed25519x25519Key(userId, passphrase); if (signOnly)
OpenPGPKey key = new OpenPGPKey(keyRing);
if (armor)
{ {
outputStream.write(key.toAsciiArmoredString().getBytes(StandardCharsets.UTF_8)); PGPSecretKeyRing keyRing = generator.signOnlyKey(passphrase);
key = new OpenPGPKey(keyRing);
} }
else else
{ {
keyRing.encode(outputStream); PGPSecretKeyRing keyRing = generator.ed25519x25519Key(userId, passphrase);
key = new OpenPGPKey(keyRing);
} }
} }
catch (PGPException e) catch (PGPException e)
{ {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
if (armor)
{
outputStream.write(key.toAsciiArmoredString().getBytes(StandardCharsets.UTF_8));
}
else
{
key.getPGPKeyRing().encode(outputStream);
}
} }
}; };
} }

View file

@ -17,9 +17,11 @@ import java.io.OutputStream;
public class BCInlineSign public class BCInlineSign
extends AbstractBCOperation extends AbstractBCOperation
implements InlineSign { implements InlineSign
{
private final OpenPGPMessageGenerator mGen = new OpenPGPMessageGenerator(); private final OpenPGPMessageGenerator mGen = new OpenPGPMessageGenerator();
private char[] keyPassword;
@NotNull @NotNull
@Override @Override
@ -52,12 +54,13 @@ 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)); mGen.addSigningKey(OpenPGPKey.fromInputStream(inputStream), k -> keyPassword);
return this; return this;
} }
@Override @Override
public InlineSign withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable { public InlineSign withKeyPassword(@NotNull byte[] bytes) throws SOPGPException.UnsupportedOption, SOPGPException.PasswordNotHumanReadable {
this.keyPassword = new String(bytes).toCharArray();
return this; return this;
} }
} }

View file

@ -26,7 +26,7 @@ public class BCInlineVerify
@NotNull @NotNull
@Override @Override
public ReadyWithResult<List<Verification>> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData { public ReadyWithResult<List<Verification>> data(@NotNull InputStream inputStream) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData {
return new ReadyWithResult<List<Verification>>() { return new ReadyWithResult<>() {
@Override @Override
public List<Verification> writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException { public List<Verification> writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
try { try {
@ -34,7 +34,12 @@ public class BCInlineVerify
Streams.pipeAll(mIn, outputStream); Streams.pipeAll(mIn, outputStream);
mIn.close(); mIn.close();
OpenPGPMessageInputStream.Result result = mIn.getResult(); OpenPGPMessageInputStream.Result result = mIn.getResult();
return getVerifications(result); List<Verification> verifications = getVerifications(result.getSignatures());
if (verifications.isEmpty())
{
throw new SOPGPException.NoSignature();
}
return verifications;
} catch (PGPException e) { } catch (PGPException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -48,12 +48,12 @@
<dependency> <dependency>
<groupId>org.pgpainless</groupId> <groupId>org.pgpainless</groupId>
<artifactId>sop-java</artifactId> <artifactId>sop-java</artifactId>
<version>10.0.0</version> <version>10.0.3-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.pgpainless</groupId> <groupId>org.pgpainless</groupId>
<artifactId>sop-java-picocli</artifactId> <artifactId>sop-java-picocli</artifactId>
<version>10.0.0</version> <version>10.0.3-SNAPSHOT</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>