mirror of
https://codeberg.org/PGPainless/sop-java.git
synced 2024-11-17 21:12:07 +01:00
decrypt: Parse out sessionkey and verifications, sign: parse out micalg
This commit is contained in:
parent
e3b618a0a8
commit
d079a345d2
4 changed files with 109 additions and 11 deletions
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
verifyOut.delete();
|
||||||
|
if (verifyWithCounter != 0) {
|
||||||
commandList.add("--verify-out=" + verifyOut.getAbsolutePath());
|
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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue