Introduce SigningResult class to allow for additional signing information to be returned

This commit is contained in:
Paul Schaub 2022-01-08 17:28:19 +01:00
parent 987c328ad8
commit f2d88d8a86
5 changed files with 70 additions and 15 deletions

View File

@ -28,6 +28,7 @@ import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.util.ArmoredOutputStreamFactory;
import sop.MicAlg;
import sop.ReadyWithResult;
import sop.SigningResult;
import sop.enums.SignAs;
import sop.exception.SOPGPException;
import sop.operation.Sign;
@ -69,7 +70,7 @@ public class SignImpl implements Sign {
}
@Override
public ReadyWithResult<MicAlg> data(InputStream data) throws IOException {
public ReadyWithResult<SigningResult> data(InputStream data) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try {
EncryptionStream signingStream = PGPainless.encryptAndOrSign()
@ -77,9 +78,9 @@ public class SignImpl implements Sign {
.withOptions(ProducerOptions.sign(signingOptions)
.setAsciiArmor(armor));
return new ReadyWithResult<MicAlg>() {
return new ReadyWithResult<SigningResult>() {
@Override
public MicAlg writeTo(OutputStream outputStream) throws IOException {
public SigningResult writeTo(OutputStream outputStream) throws IOException {
if (signingStream.isClosed()) {
throw new IllegalStateException("EncryptionStream is already closed.");
@ -106,7 +107,9 @@ public class SignImpl implements Sign {
out.close();
outputStream.close(); // armor out does not close underlying stream
return micAlgFromSignatures(signatures);
return SigningResult.builder()
.setMicAlg(micAlgFromSignatures(signatures))
.build();
}
};

View File

@ -15,6 +15,7 @@ import java.util.List;
import picocli.CommandLine;
import sop.MicAlg;
import sop.ReadyWithResult;
import sop.SigningResult;
import sop.cli.picocli.Print;
import sop.cli.picocli.SopCLI;
import sop.enums.SignAs;
@ -93,9 +94,10 @@ public class SignCmd implements Runnable {
}
try {
ReadyWithResult<MicAlg> ready = sign.data(System.in);
MicAlg micAlg = ready.writeTo(System.out);
ReadyWithResult<SigningResult> ready = sign.data(System.in);
SigningResult result = ready.writeTo(System.out);
MicAlg micAlg = result.getMicAlg();
if (micAlgOut != null) {
// Write micalg out
micAlgOut.createNewFile();

View File

@ -19,9 +19,9 @@ import java.io.OutputStream;
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import sop.MicAlg;
import sop.ReadyWithResult;
import sop.SOP;
import sop.SigningResult;
import sop.cli.picocli.SopCLI;
import sop.exception.SOPGPException;
import sop.operation.Sign;
@ -34,10 +34,10 @@ public class SignCmdTest {
@BeforeEach
public void mockComponents() throws IOException, SOPGPException.ExpectedText {
sign = mock(Sign.class);
when(sign.data((InputStream) any())).thenReturn(new ReadyWithResult<MicAlg>() {
when(sign.data((InputStream) any())).thenReturn(new ReadyWithResult<SigningResult>() {
@Override
public MicAlg writeTo(OutputStream outputStream) {
return MicAlg.fromHashAlgorithmId(10);
public SigningResult writeTo(OutputStream outputStream) {
return SigningResult.builder().build();
}
});
@ -110,9 +110,9 @@ public class SignCmdTest {
@Test
@ExpectSystemExitWithStatus(1)
public void data_ioExceptionCausesExit1() throws IOException, SOPGPException.ExpectedText {
when(sign.data((InputStream) any())).thenReturn(new ReadyWithResult<MicAlg>() {
when(sign.data((InputStream) any())).thenReturn(new ReadyWithResult<SigningResult>() {
@Override
public MicAlg writeTo(OutputStream outputStream) throws IOException {
public SigningResult writeTo(OutputStream outputStream) throws IOException {
throw new IOException();
}
});

View File

@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package sop;
/**
* This class contains various information about a signed message.
*/
public final class SigningResult {
private final MicAlg micAlg;
private SigningResult(MicAlg micAlg) {
this.micAlg = micAlg;
}
/**
* Return a string identifying the digest mechanism used to create the signed message.
* This is useful for setting the micalg= parameter for the multipart/signed
* content type of a PGP/MIME object as described in section 5 of [RFC3156].
*
* If more than one signature was generated and different digest mechanisms were used,
* the value of the micalg object is an empty string.
*
* @return micalg
*/
public MicAlg getMicAlg() {
return micAlg;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private MicAlg micAlg;
public Builder setMicAlg(MicAlg micAlg) {
this.micAlg = micAlg;
return this;
}
public SigningResult build() {
SigningResult signingResult = new SigningResult(micAlg);
return signingResult;
}
}
}

View File

@ -8,8 +8,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import sop.MicAlg;
import sop.ReadyWithResult;
import sop.SigningResult;
import sop.enums.SignAs;
import sop.exception.SOPGPException;
@ -55,7 +55,7 @@ public interface Sign {
* @param data input stream containing data
* @return ready
*/
ReadyWithResult<MicAlg> data(InputStream data) throws IOException, SOPGPException.ExpectedText;
ReadyWithResult<SigningResult> data(InputStream data) throws IOException, SOPGPException.ExpectedText;
/**
* Signs data.
@ -63,7 +63,7 @@ public interface Sign {
* @param data byte array containing data
* @return ready
*/
default ReadyWithResult<MicAlg> data(byte[] data) throws IOException, SOPGPException.ExpectedText {
default ReadyWithResult<SigningResult> data(byte[] data) throws IOException, SOPGPException.ExpectedText {
return data(new ByteArrayInputStream(data));
}
}