mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-16 01:12:05 +01:00
Fix various checkstyle issues
This commit is contained in:
parent
ffd46b6d5e
commit
31cfbaa4b2
11 changed files with 350 additions and 74 deletions
|
@ -1,6 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop;
|
package org.pgpainless.sop;
|
||||||
|
|
||||||
import org.pgpainless.sop.commands.*;
|
import org.pgpainless.sop.commands.Armor;
|
||||||
|
import org.pgpainless.sop.commands.Dearmor;
|
||||||
|
import org.pgpainless.sop.commands.ExtractCert;
|
||||||
|
import org.pgpainless.sop.commands.GenerateKey;
|
||||||
|
import org.pgpainless.sop.commands.Sign;
|
||||||
|
import org.pgpainless.sop.commands.Verify;
|
||||||
|
import org.pgpainless.sop.commands.Version;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
@CommandLine.Command(
|
@CommandLine.Command(
|
||||||
|
@ -9,36 +30,17 @@ import picocli.CommandLine;
|
||||||
GenerateKey.class,
|
GenerateKey.class,
|
||||||
ExtractCert.class,
|
ExtractCert.class,
|
||||||
Sign.class,
|
Sign.class,
|
||||||
Verify.class
|
Verify.class,
|
||||||
|
Armor.class,
|
||||||
|
Dearmor.class
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
public class PGPainlessCLI implements Runnable {
|
public class PGPainlessCLI implements Runnable {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
interpret(args);
|
|
||||||
// generateKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void interpret(String... args) {
|
|
||||||
CommandLine.run(new PGPainlessCLI(), args);
|
CommandLine.run(new PGPainlessCLI(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void version() {
|
|
||||||
CommandLine.run(new PGPainlessCLI(), "version");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void generateKey() {
|
|
||||||
interpret("generate-key", "--armor", "Alice Example <alice@wonderland.lit>");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void extractCert() {
|
|
||||||
CommandLine.run(new PGPainlessCLI(), "extract-cert");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void sign() {
|
|
||||||
interpret("sign", "--armor", "--as=text", "alice.sec");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop;
|
package org.pgpainless.sop;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -13,4 +28,16 @@ public class Print {
|
||||||
return new String(bytes, "UTF-8");
|
return new String(bytes, "UTF-8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void print_ln(String msg) {
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
System.out.println(msg);
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void err_ln(String msg) {
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
System.err.println(msg);
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
|
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||||
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PushbackInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.err_ln;
|
||||||
|
|
||||||
|
@CommandLine.Command(name = "armor", description = "Add ASCII Armor")
|
||||||
|
public class Armor implements Runnable {
|
||||||
|
|
||||||
|
private static final byte[] BEGIN_ARMOR = "-----BEGIN PGP".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
private enum Label {
|
||||||
|
auto,
|
||||||
|
sig,
|
||||||
|
key,
|
||||||
|
cert,
|
||||||
|
message
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandLine.Option(names = {"--label"}, description = "Label to be used in the header and tail of the armoring.", paramLabel = "{auto|sig|key|cert|message}")
|
||||||
|
Label label;
|
||||||
|
|
||||||
|
@CommandLine.Option(names = {"--allow-nested"}, description = "Allow additional armoring of already armored input")
|
||||||
|
boolean allowNested = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
try (PushbackInputStream pbIn = new PushbackInputStream(System.in); ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(System.out)) {
|
||||||
|
byte[] start = new byte[14];
|
||||||
|
int read = pbIn.read(start);
|
||||||
|
pbIn.unread(read);
|
||||||
|
if (Arrays.equals(BEGIN_ARMOR, start) && !allowNested) {
|
||||||
|
Streams.pipeAll(pbIn, System.out);
|
||||||
|
} else {
|
||||||
|
Streams.pipeAll(pbIn, armoredOutputStream);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
err_ln("Input data cannot be ASCII armored.");
|
||||||
|
err_ln(e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
|
import org.bouncycastle.bcpg.ArmoredInputStream;
|
||||||
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.err_ln;
|
||||||
|
|
||||||
|
@CommandLine.Command(name = "dearmor", description = "Remove ASCII Armor")
|
||||||
|
public class Dearmor implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try (ArmoredInputStream in = new ArmoredInputStream(System.in, true)) {
|
||||||
|
Streams.pipeAll(in, System.out);
|
||||||
|
} catch (IOException e) {
|
||||||
|
err_ln("Data cannot be dearmored.");
|
||||||
|
err_ln(e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop.commands;
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -10,6 +25,9 @@ import org.pgpainless.sop.Print;
|
||||||
import org.pgpainless.util.BCUtil;
|
import org.pgpainless.util.BCUtil;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.err_ln;
|
||||||
|
import static org.pgpainless.sop.Print.print_ln;
|
||||||
|
|
||||||
@CommandLine.Command(name = "extract-cert")
|
@CommandLine.Command(name = "extract-cert")
|
||||||
public class ExtractCert implements Runnable {
|
public class ExtractCert implements Runnable {
|
||||||
|
|
||||||
|
@ -25,10 +43,10 @@ public class ExtractCert implements Runnable {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(System.in);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(System.in);
|
||||||
PGPPublicKeyRing publicKeys = BCUtil.publicKeyRingFromSecretKeyRing(secretKeys);
|
PGPPublicKeyRing publicKeys = BCUtil.publicKeyRingFromSecretKeyRing(secretKeys);
|
||||||
|
|
||||||
System.out.println(Print.toString(publicKeys.getEncoded(), !noArmor));
|
print_ln(Print.toString(publicKeys.getEncoded(), !noArmor));
|
||||||
} catch (IOException | PGPException e) {
|
} catch (IOException | PGPException e) {
|
||||||
System.err.println("Error extracting certificate from keys;");
|
err_ln("Error extracting certificate from keys;");
|
||||||
System.err.println(e.getMessage());
|
err_ln(e.getMessage());
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop.commands;
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -8,9 +23,11 @@ import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.sop.Print;
|
import org.pgpainless.sop.Print;
|
||||||
import org.pgpainless.util.ArmorUtils;
|
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.err_ln;
|
||||||
|
import static org.pgpainless.sop.Print.print_ln;
|
||||||
|
|
||||||
@CommandLine.Command(name = "generate-key")
|
@CommandLine.Command(name = "generate-key")
|
||||||
public class GenerateKey implements Runnable {
|
public class GenerateKey implements Runnable {
|
||||||
|
|
||||||
|
@ -28,11 +45,11 @@ public class GenerateKey implements Runnable {
|
||||||
try {
|
try {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing(userId);
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing(userId);
|
||||||
|
|
||||||
System.out.println(Print.toString(secretKeys.getEncoded(), !noArmor));
|
print_ln(Print.toString(secretKeys.getEncoded(), !noArmor));
|
||||||
|
|
||||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | PGPException | IOException e) {
|
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | PGPException | IOException e) {
|
||||||
System.err.println("Error creating OpenPGP key:");
|
err_ln("Error creating OpenPGP key:");
|
||||||
System.err.println(e.getMessage());
|
err_ln(e.getMessage());
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop.commands;
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
@ -16,6 +31,9 @@ import org.pgpainless.key.protection.UnprotectedKeysProtector;
|
||||||
import org.pgpainless.sop.Print;
|
import org.pgpainless.sop.Print;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.err_ln;
|
||||||
|
import static org.pgpainless.sop.Print.print_ln;
|
||||||
|
|
||||||
@CommandLine.Command(name = "sign")
|
@CommandLine.Command(name = "sign")
|
||||||
public class Sign implements Runnable {
|
public class Sign implements Runnable {
|
||||||
|
|
||||||
|
@ -30,7 +48,8 @@ public class Sign implements Runnable {
|
||||||
@CommandLine.Option(names = {"--no-armor"})
|
@CommandLine.Option(names = {"--no-armor"})
|
||||||
boolean noArmor = false;
|
boolean noArmor = false;
|
||||||
|
|
||||||
@CommandLine.Option(names = "--as", description = "Defaults to 'binary'. If '--as=text' and the input data is not valid UTF-8, sign fails with return code 53.")
|
@CommandLine.Option(names = "--as", description = "Defaults to 'binary'. If '--as=text' and the input data is not valid UTF-8, sign fails with return code 53.",
|
||||||
|
paramLabel = "{binary|text}")
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
@CommandLine.Parameters
|
@CommandLine.Parameters
|
||||||
|
@ -42,9 +61,8 @@ public class Sign implements Runnable {
|
||||||
try {
|
try {
|
||||||
secretKeys = PGPainless.readKeyRing().secretKeyRing(new FileInputStream(secretKeyFile));
|
secretKeys = PGPainless.readKeyRing().secretKeyRing(new FileInputStream(secretKeyFile));
|
||||||
} catch (IOException | PGPException e) {
|
} catch (IOException | PGPException e) {
|
||||||
System.err.println("Error reading secret key ring.");
|
err_ln("Error reading secret key ring.");
|
||||||
System.err.println(e.getMessage());
|
err_ln(e.getMessage());
|
||||||
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,11 +82,10 @@ public class Sign implements Runnable {
|
||||||
|
|
||||||
PGPSignature signature = encryptionStream.getResult().getSignatures().iterator().next();
|
PGPSignature signature = encryptionStream.getResult().getSignatures().iterator().next();
|
||||||
|
|
||||||
System.out.println(Print.toString(signature.getEncoded(), !noArmor));
|
print_ln(Print.toString(signature.getEncoded(), !noArmor));
|
||||||
} catch (PGPException | IOException e) {
|
} catch (PGPException | IOException e) {
|
||||||
System.err.println("Error signing data.");
|
err_ln("Error signing data.");
|
||||||
System.err.println(e.getMessage());
|
err_ln(e.getMessage());
|
||||||
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop.commands;
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
@ -12,6 +27,7 @@ import picocli.CommandLine;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
@ -23,9 +39,22 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.err_ln;
|
||||||
|
import static org.pgpainless.sop.Print.print_ln;
|
||||||
|
|
||||||
@CommandLine.Command(name = "verify", description = "Verify a detached signature.\nThe signed data is being read from standard input.")
|
@CommandLine.Command(name = "verify", description = "Verify a detached signature.\nThe signed data is being read from standard input.")
|
||||||
public class Verify implements Runnable {
|
public class Verify implements Runnable {
|
||||||
|
|
||||||
|
private static final TimeZone tz = TimeZone.getTimeZone("UTC");
|
||||||
|
private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
|
||||||
|
|
||||||
|
private static final Date beginningOfTime = new Date(0);
|
||||||
|
private static final Date endOfTime = new Date(8640000000000000L);
|
||||||
|
|
||||||
|
static {
|
||||||
|
df.setTimeZone(tz);
|
||||||
|
}
|
||||||
|
|
||||||
@CommandLine.Parameters(index = "0", description = "Detached signature")
|
@CommandLine.Parameters(index = "0", description = "Detached signature")
|
||||||
File signature;
|
File signature;
|
||||||
|
|
||||||
|
@ -43,24 +72,18 @@ public class Verify implements Runnable {
|
||||||
"Accepts special value \"-\" for end of time.")
|
"Accepts special value \"-\" for end of time.")
|
||||||
String notAfter = "now";
|
String notAfter = "now";
|
||||||
|
|
||||||
private final TimeZone tz = TimeZone.getTimeZone("UTC");
|
|
||||||
private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
|
|
||||||
|
|
||||||
private final Date beginningOfTime = new Date(0);
|
|
||||||
private final Date endOfTime = new Date(8640000000000000L);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
df.setTimeZone(tz);
|
|
||||||
Date notBeforeDate = parseNotBefore();
|
Date notBeforeDate = parseNotBefore();
|
||||||
Date notAfterDate = parseNotAfter();
|
Date notAfterDate = parseNotAfter();
|
||||||
|
|
||||||
Map<File, PGPPublicKeyRing> publicKeys = readCertificatesFromFiles();
|
Map<File, PGPPublicKeyRing> publicKeys = readCertificatesFromFiles();
|
||||||
if (publicKeys.isEmpty()) {
|
if (publicKeys.isEmpty()) {
|
||||||
System.out.println("No certificates supplied.");
|
err_ln("No certificates supplied.");
|
||||||
System.exit(19);
|
System.exit(19);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenPgpMetadata metadata;
|
||||||
try (FileInputStream sigIn = new FileInputStream(signature)) {
|
try (FileInputStream sigIn = new FileInputStream(signature)) {
|
||||||
DecryptionStream verifier = PGPainless.decryptAndOrVerify()
|
DecryptionStream verifier = PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(System.in)
|
.onInputStream(System.in)
|
||||||
|
@ -74,7 +97,18 @@ public class Verify implements Runnable {
|
||||||
Streams.pipeAll(verifier, out);
|
Streams.pipeAll(verifier, out);
|
||||||
verifier.close();
|
verifier.close();
|
||||||
|
|
||||||
OpenPgpMetadata metadata = verifier.getResult();
|
metadata = verifier.getResult();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
err_ln("Signature file not found:");
|
||||||
|
err_ln(e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
return;
|
||||||
|
} catch (IOException | PGPException e) {
|
||||||
|
err_ln("Signature validation failed.");
|
||||||
|
err_ln(e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Map<OpenPgpV4Fingerprint, PGPSignature> signaturesInTimeRange = new HashMap<>();
|
Map<OpenPgpV4Fingerprint, PGPSignature> signaturesInTimeRange = new HashMap<>();
|
||||||
for (OpenPgpV4Fingerprint fingerprint : metadata.getVerifiedSignatures().keySet()) {
|
for (OpenPgpV4Fingerprint fingerprint : metadata.getVerifiedSignatures().keySet()) {
|
||||||
|
@ -86,14 +120,11 @@ public class Verify implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signaturesInTimeRange.isEmpty()) {
|
if (signaturesInTimeRange.isEmpty()) {
|
||||||
System.out.println("Signature validation failed.");
|
err_ln("No valid signatures found.");
|
||||||
System.exit(3);
|
System.exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
printValidSignatures(signaturesInTimeRange, publicKeys);
|
printValidSignatures(signaturesInTimeRange, publicKeys);
|
||||||
} catch (IOException | PGPException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printValidSignatures(Map<OpenPgpV4Fingerprint, PGPSignature> validSignatures, Map<File, PGPPublicKeyRing> publicKeys) {
|
private void printValidSignatures(Map<OpenPgpV4Fingerprint, PGPSignature> validSignatures, Map<File, PGPPublicKeyRing> publicKeys) {
|
||||||
|
@ -108,7 +139,7 @@ public class Verify implements Runnable {
|
||||||
|
|
||||||
String utcSigDate = df.format(signature.getCreationTime());
|
String utcSigDate = df.format(signature.getCreationTime());
|
||||||
OpenPgpV4Fingerprint primaryKeyFp = new OpenPgpV4Fingerprint(publicKeyRing);
|
OpenPgpV4Fingerprint primaryKeyFp = new OpenPgpV4Fingerprint(publicKeyRing);
|
||||||
System.out.println(utcSigDate + " " + sigKeyFp.toString() + " " + primaryKeyFp.toString() +
|
print_ln(utcSigDate + " " + sigKeyFp.toString() + " " + primaryKeyFp.toString() +
|
||||||
" signed by " + file.getName());
|
" signed by " + file.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +151,8 @@ public class Verify implements Runnable {
|
||||||
try (FileInputStream in = new FileInputStream(cert)) {
|
try (FileInputStream in = new FileInputStream(cert)) {
|
||||||
publicKeys.put(cert, PGPainless.readKeyRing().publicKeyRing(in));
|
publicKeys.put(cert, PGPainless.readKeyRing().publicKeyRing(in));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
err_ln("Cannot read certificate from file " + cert.getAbsolutePath() + ":");
|
||||||
|
err_ln(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return publicKeys;
|
return publicKeys;
|
||||||
|
@ -130,7 +162,7 @@ public class Verify implements Runnable {
|
||||||
try {
|
try {
|
||||||
return notAfter.equals("now") ? new Date() : notAfter.equals("-") ? endOfTime : df.parse(notAfter);
|
return notAfter.equals("now") ? new Date() : notAfter.equals("-") ? endOfTime : df.parse(notAfter);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
System.out.println("Invalid date string supplied as value of --not-after.");
|
err_ln("Invalid date string supplied as value of --not-after.");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +172,7 @@ public class Verify implements Runnable {
|
||||||
try {
|
try {
|
||||||
return notBefore.equals("now") ? new Date() : notBefore.equals("-") ? beginningOfTime : df.parse(notBefore);
|
return notBefore.equals("now") ? new Date() : notBefore.equals("-") ? beginningOfTime : df.parse(notBefore);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
System.out.println("Invalid date string supplied as value of --not-before.");
|
err_ln("Invalid date string supplied as value of --not-before.");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
package org.pgpainless.sop.commands;
|
package org.pgpainless.sop.commands;
|
||||||
|
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import static org.pgpainless.sop.Print.print_ln;
|
||||||
|
|
||||||
@CommandLine.Command(name = "version", description = "Display version information about the tool")
|
@CommandLine.Command(name = "version", description = "Display version information about the tool")
|
||||||
public class Version implements Runnable {
|
public class Version implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
System.out.println("PGPainless CLI version 0.0.1");
|
print_ln("PGPainless CLI version 0.0.1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Subcommands of the PGPainless SOP.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.sop.commands;
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* PGPainless SOP implementing a Stateless OpenPGP Command Line Interface.
|
||||||
|
* @see <a href="https://tools.ietf.org/html/draft-dkg-openpgp-stateless-cli-01">
|
||||||
|
* Stateless OpenPGP Command Line Interface
|
||||||
|
* draft-dkg-openpgp-stateless-cli-01</a>
|
||||||
|
*/
|
||||||
|
package org.pgpainless.sop;
|
Loading…
Reference in a new issue