Treat password and sessionkkey arguments as indirect data types

This commit is contained in:
Paul Schaub 2022-02-09 15:12:23 +01:00
parent a2f2069380
commit 117117b735
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
8 changed files with 134 additions and 42 deletions

View file

@ -4,10 +4,13 @@
package sop.cli.picocli;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import sop.exception.SOPGPException;
@ -95,4 +98,17 @@ public class FileUtil {
}
return file;
}
public static String stringFromInputStream(InputStream inputStream) throws IOException {
try {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
byte[] buf = new byte[4096]; int read;
while ((read = inputStream.read(buf)) != -1) {
byteOut.write(buf, 0, read);
}
return new String(byteOut.toByteArray(), Charset.forName("UTF8"));
} finally {
inputStream.close();
}
}
}

View file

@ -47,13 +47,13 @@ public class DecryptCmd implements Runnable {
@CommandLine.Option(
names = {"--with-session-key"},
description = "Enables decryption of the \"CIPHERTEXT\" using the session key directly against the \"SEIPD\" packet",
description = "Provide a session key file. Enables decryption of the \"CIPHERTEXT\" using the session key directly against the \"SEIPD\" packet",
paramLabel = "SESSIONKEY")
List<String> withSessionKey = new ArrayList<>();
@CommandLine.Option(
names = {"--with-password"},
description = "Enables decryption based on any \"SKESK\" packets in the \"CIPHERTEXT\"",
description = "Provide a password file. Enables decryption based on any \"SKESK\" packets in the \"CIPHERTEXT\"",
paramLabel = "PASSWORD")
List<String> withPassword = new ArrayList<>();
@ -194,7 +194,13 @@ public class DecryptCmd implements Runnable {
private void setWithSessionKeys(List<String> withSessionKey, Decrypt decrypt) {
Pattern sessionKeyPattern = Pattern.compile("^\\d+:[0-9A-F]+$");
for (String sessionKey : withSessionKey) {
for (String sessionKeyFile : withSessionKey) {
String sessionKey;
try {
sessionKey = FileUtil.stringFromInputStream(FileUtil.getFileInputStream(sessionKeyFile));
} catch (IOException e) {
throw new SOPGPException.BadData("Cannot read session key from session key file " + sessionKeyFile, e);
}
if (!sessionKeyPattern.matcher(sessionKey).matches()) {
throw new IllegalArgumentException("Session keys are expected in the format 'ALGONUM:HEXKEY'.");
}
@ -211,11 +217,14 @@ public class DecryptCmd implements Runnable {
}
private void setWithPasswords(List<String> withPassword, Decrypt decrypt) {
for (String password : withPassword) {
for (String passwordFile : withPassword) {
try {
String password = FileUtil.stringFromInputStream(FileUtil.getFileInputStream(passwordFile));
decrypt.withPassword(password);
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
throw new SOPGPException.UnsupportedOption(String.format(ERROR_UNSUPPORTED_OPTION, "--with-password"), unsupportedOption);
} catch (IOException e) {
throw new SOPGPException.PasswordNotHumanReadable("Cannot read password from password file " + passwordFile, e);
}
}
}

View file

@ -13,6 +13,7 @@ import java.util.List;
import picocli.CommandLine;
import sop.Ready;
import sop.cli.picocli.FileUtil;
import sop.cli.picocli.SopCLI;
import sop.enums.EncryptAs;
import sop.exception.SOPGPException;
@ -34,7 +35,7 @@ public class EncryptCmd implements Runnable {
EncryptAs type;
@CommandLine.Option(names = "--with-password",
description = "Encrypt the message with a password",
description = "Encrypt the message with a password provided by the given password file",
paramLabel = "PASSWORD")
List<String> withPassword = new ArrayList<>();
@ -64,14 +65,17 @@ public class EncryptCmd implements Runnable {
}
if (withPassword.isEmpty() && certs.isEmpty()) {
throw new SOPGPException.MissingArg("At least one password or cert file required for encryption.");
throw new SOPGPException.MissingArg("At least one password file or cert file required for encryption.");
}
for (String password : withPassword) {
for (String passwordFileName : withPassword) {
try {
String password = FileUtil.stringFromInputStream(FileUtil.getFileInputStream(passwordFileName));
encrypt.withPassword(password);
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
throw new SOPGPException.UnsupportedOption("Unsupported option '--with-password'.", unsupportedOption);
} catch (IOException e) {
throw new SOPGPException.PasswordNotHumanReadable("Cannot read password from the provided password file " + passwordFileName, e);
}
}