decrypt: Parse out sessionkey and verifications, sign: parse out micalg

This commit is contained in:
Paul Schaub 2023-01-12 14:40:00 +01:00
parent e3b618a0a8
commit d079a345d2
4 changed files with 109 additions and 11 deletions

View file

@ -83,7 +83,7 @@ public class ExternalSOP implements SOP {
@Override @Override
public DetachedSign detachedSign() { public DetachedSign detachedSign() {
return new DetachedSignExternal(binaryName, properties); return new DetachedSignExternal(binaryName, properties, tempDirProvider);
} }
@Override @Override

View file

@ -7,17 +7,20 @@ package sop.external.operation;
import sop.DecryptionResult; import sop.DecryptionResult;
import sop.ReadyWithResult; import sop.ReadyWithResult;
import sop.SessionKey; import sop.SessionKey;
import sop.Verification;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import sop.external.ExternalSOP; import sop.external.ExternalSOP;
import sop.operation.Decrypt; import sop.operation.Decrypt;
import sop.util.UTCUtil; import sop.util.UTCUtil;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
@ -104,13 +107,17 @@ public class DecryptExternal implements Decrypt {
public ReadyWithResult<DecryptionResult> ciphertext(InputStream ciphertext) public ReadyWithResult<DecryptionResult> ciphertext(InputStream ciphertext)
throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt, throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt,
SOPGPException.KeyIsProtected, IOException { SOPGPException.KeyIsProtected, IOException {
File tempDir = tempDirProvider.provideTempDirectory(); File tempDir = tempDirProvider.provideTempDirectory();
File sessionKeyOut = new File(tempDir, "session-key-out"); File sessionKeyOut = new File(tempDir, "session-key-out");
sessionKeyOut.delete();
commandList.add("--session-key-out=" + sessionKeyOut.getAbsolutePath()); commandList.add("--session-key-out=" + sessionKeyOut.getAbsolutePath());
File verifyOut = new File(tempDir, "verify-out"); File verifyOut = new File(tempDir, "verifications-out");
commandList.add("--verify-out=" + verifyOut.getAbsolutePath()); verifyOut.delete();
if (verifyWithCounter != 0) {
commandList.add("--verify-out=" + verifyOut.getAbsolutePath());
}
String[] command = commandList.toArray(new String[0]); String[] command = commandList.toArray(new String[0]);
String[] env = envList.toArray(new String[0]); String[] env = envList.toArray(new String[0]);
@ -140,7 +147,23 @@ public class DecryptExternal implements Decrypt {
ExternalSOP.finish(process); ExternalSOP.finish(process);
return new DecryptionResult(null, Collections.emptyList()); // TODO FileInputStream sessionKeyOutIn = new FileInputStream(sessionKeyOut);
String line = ExternalSOP.readFully(sessionKeyOutIn);
SessionKey sessionKey = SessionKey.fromString(line.trim());
sessionKeyOutIn.close();
sessionKeyOut.delete();
List<Verification> verifications = new ArrayList<>();
if (verifyWithCounter != 0) {
FileInputStream verifyOutIn = new FileInputStream(verifyOut);
BufferedReader reader = new BufferedReader(new InputStreamReader(verifyOutIn));
while ((line = reader.readLine()) != null) {
verifications.add(Verification.fromString(line.trim()));
}
reader.close();
}
return new DecryptionResult(sessionKey, verifications); // TODO
} }
}; };
} catch (IOException e) { } catch (IOException e) {

View file

@ -4,6 +4,7 @@
package sop.external.operation; package sop.external.operation;
import sop.MicAlg;
import sop.ReadyWithResult; import sop.ReadyWithResult;
import sop.SigningResult; import sop.SigningResult;
import sop.enums.SignAs; import sop.enums.SignAs;
@ -11,8 +12,12 @@ import sop.exception.SOPGPException;
import sop.external.ExternalSOP; import sop.external.ExternalSOP;
import sop.operation.DetachedSign; import sop.operation.DetachedSign;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -20,13 +25,15 @@ import java.util.Properties;
public class DetachedSignExternal implements DetachedSign { public class DetachedSignExternal implements DetachedSign {
private final ExternalSOP.TempDirProvider tempDirProvider;
private final List<String> commandList = new ArrayList<>(); private final List<String> commandList = new ArrayList<>();
private final List<String> envList; private final List<String> envList;
private int withKeyPasswordCounter = 0; private int withKeyPasswordCounter = 0;
private int keyCounter = 0; private int keyCounter = 0;
public DetachedSignExternal(String binary, Properties properties) { public DetachedSignExternal(String binary, Properties properties, ExternalSOP.TempDirProvider tempDirProvider) {
this.tempDirProvider = tempDirProvider;
commandList.add(binary); commandList.add(binary);
commandList.add("sign"); commandList.add("sign");
envList = ExternalSOP.propertiesToEnv(properties); envList = ExternalSOP.propertiesToEnv(properties);
@ -64,6 +71,11 @@ public class DetachedSignExternal implements DetachedSign {
public ReadyWithResult<SigningResult> data(InputStream data) public ReadyWithResult<SigningResult> data(InputStream data)
throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText { throws IOException, SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
File tempDir = tempDirProvider.provideTempDirectory();
File micAlgOut = new File(tempDir, "micAlgOut");
micAlgOut.delete();
commandList.add("--micalg-out=" + micAlgOut.getAbsolutePath());
String[] command = commandList.toArray(new String[0]); String[] command = commandList.toArray(new String[0]);
String[] env = envList.toArray(new String[0]); String[] env = envList.toArray(new String[0]);
try { try {
@ -92,7 +104,18 @@ public class DetachedSignExternal implements DetachedSign {
ExternalSOP.finish(process); ExternalSOP.finish(process);
return SigningResult.builder().build(); SigningResult.Builder builder = SigningResult.builder();
if (micAlgOut.exists()) {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(micAlgOut)));
String line = reader.readLine();
if (line != null && !line.trim().isEmpty()) {
builder.setMicAlg(MicAlg.fromHashAlgorithmId(Integer.parseInt(line)));
}
reader.close();
micAlgOut.delete();
}
return builder.build();
} }
}; };
} catch (IOException e) { } catch (IOException e) {

View file

@ -6,15 +6,39 @@ package sop.external;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIf; import org.junit.jupiter.api.condition.EnabledIf;
import sop.ByteArrayAndResult;
import sop.DecryptionResult;
import sop.Verification;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnabledIf("sop.external.AbstractExternalSOPTest#isExternalSopInstalled") @EnabledIf("sop.external.AbstractExternalSOPTest#isExternalSopInstalled")
public class EncryptDecryptRoundTripTest extends AbstractExternalSOPTest { public class EncryptDecryptRoundTripTest extends AbstractExternalSOPTest {
@Test
public void encryptDecryptRoundTripPasswordTest() throws IOException {
byte[] message = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
byte[] ciphertext = getSop().encrypt()
.withPassword("sw0rdf1sh")
.plaintext(message)
.getBytes();
byte[] plaintext = getSop().decrypt()
.withPassword("sw0rdf1sh")
.ciphertext(ciphertext)
.toByteArrayAndResult()
.getBytes();
assertArrayEquals(message, plaintext);
}
@Test @Test
public void encryptDecryptRoundTripAliceTest() throws IOException { public void encryptDecryptRoundTripAliceTest() throws IOException {
byte[] message = "Hello, World!\n".getBytes(StandardCharsets.UTF_8); byte[] message = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
@ -23,13 +47,16 @@ public class EncryptDecryptRoundTripTest extends AbstractExternalSOPTest {
.plaintext(message) .plaintext(message)
.getBytes(); .getBytes();
byte[] plaintext = getSop().decrypt() ByteArrayAndResult<DecryptionResult> bytesAndResult = getSop().decrypt()
.withKey(TestKeys.ALICE_KEY.getBytes(StandardCharsets.UTF_8)) .withKey(TestKeys.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
.ciphertext(ciphertext) .ciphertext(ciphertext)
.toByteArrayAndResult() .toByteArrayAndResult();
.getBytes();
byte[] plaintext = bytesAndResult.getBytes();
assertArrayEquals(message, plaintext); assertArrayEquals(message, plaintext);
DecryptionResult result = bytesAndResult.getResult();
assertNotNull(result.getSessionKey().get());
} }
@Test @Test
@ -67,4 +94,29 @@ public class EncryptDecryptRoundTripTest extends AbstractExternalSOPTest {
assertArrayEquals(message, plaintext); assertArrayEquals(message, plaintext);
} }
@Test
public void encryptSignDecryptVerifyRoundTripAliceTest() throws IOException {
byte[] message = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
byte[] ciphertext = getSop().encrypt()
.withCert(TestKeys.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
.signWith(TestKeys.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
.plaintext(message)
.getBytes();
ByteArrayAndResult<DecryptionResult> bytesAndResult = getSop().decrypt()
.withKey(TestKeys.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
.verifyWithCert(TestKeys.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
.ciphertext(ciphertext)
.toByteArrayAndResult();
byte[] plaintext = bytesAndResult.getBytes();
assertArrayEquals(message, plaintext);
DecryptionResult result = bytesAndResult.getResult();
assertNotNull(result.getSessionKey().get());
List<Verification> verificationList = result.getVerifications();
assertEquals(1, verificationList.size());
assertTrue(verificationList.get(0).toString().contains("EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E"));
}
} }