2022-07-04 20:12:42 +02:00
|
|
|
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
package pgp.cert_d.cli.commands;
|
|
|
|
|
|
|
|
import org.bouncycastle.openpgp.PGPException;
|
|
|
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
|
|
import org.pgpainless.PGPainless;
|
|
|
|
import org.pgpainless.algorithm.KeyFlag;
|
|
|
|
import org.pgpainless.key.generation.KeyRingBuilder;
|
|
|
|
import org.pgpainless.key.generation.KeySpec;
|
|
|
|
import org.pgpainless.key.generation.type.KeyType;
|
|
|
|
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
|
|
|
import org.pgpainless.util.Passphrase;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2022-08-12 15:43:22 +02:00
|
|
|
import org.pgpainless.certificate_store.MergeCallbacks;
|
2022-07-04 20:12:42 +02:00
|
|
|
import pgp.cert_d.cli.PGPCertDCli;
|
2022-09-01 11:29:47 +02:00
|
|
|
import pgp.certificate_store.certificate.KeyMaterial;
|
2022-08-12 15:04:54 +02:00
|
|
|
import pgp.certificate_store.exception.BadDataException;
|
2022-07-04 20:12:42 +02:00
|
|
|
import picocli.CommandLine;
|
|
|
|
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.security.InvalidAlgorithmParameterException;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
|
|
|
|
@CommandLine.Command(name = "setup",
|
2022-08-04 13:46:36 +02:00
|
|
|
resourceBundle = "msg_setup")
|
2022-07-04 20:12:42 +02:00
|
|
|
public class Setup implements Runnable {
|
|
|
|
|
|
|
|
public static final Logger LOGGER = LoggerFactory.getLogger(Setup.class);
|
|
|
|
|
|
|
|
@CommandLine.ArgGroup()
|
|
|
|
Exclusive exclusive;
|
|
|
|
|
|
|
|
static class Exclusive {
|
|
|
|
@CommandLine.Option(names = "--with-password",
|
2022-08-04 13:46:36 +02:00
|
|
|
paramLabel = "PASSWORD")
|
2022-07-04 20:12:42 +02:00
|
|
|
String password;
|
|
|
|
|
|
|
|
@CommandLine.Option(names = "--import-from-stdin",
|
|
|
|
description = "Import trust-root from stdin")
|
|
|
|
boolean importFromStdin;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
PGPSecretKeyRing trustRoot;
|
|
|
|
if (exclusive == null) {
|
|
|
|
trustRoot = generateTrustRoot(Passphrase.emptyPassphrase());
|
|
|
|
} else {
|
|
|
|
if (exclusive.importFromStdin) {
|
|
|
|
trustRoot = readTrustRoot(System.in);
|
|
|
|
} else {
|
|
|
|
trustRoot = generateTrustRoot(Passphrase.fromPassword(exclusive.password.trim()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
InputStream inputStream = new ByteArrayInputStream(trustRoot.getEncoded());
|
2022-09-01 11:29:47 +02:00
|
|
|
KeyMaterial inserted = PGPCertDCli.getCertificateDirectory()
|
|
|
|
.insertTrustRoot(inputStream, MergeCallbacks.overrideExisting());
|
|
|
|
// CHECKSTYLE:OFF
|
|
|
|
System.out.println(inserted.getFingerprint());
|
|
|
|
// CHECKSTYLE:ON
|
2022-07-04 20:12:42 +02:00
|
|
|
|
|
|
|
} catch (BadDataException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
} catch (IOException e) {
|
|
|
|
LOGGER.error("IO error.", e);
|
|
|
|
System.exit(-1);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
LOGGER.error("Thread interrupted.", e);
|
|
|
|
System.exit(-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private PGPSecretKeyRing generateTrustRoot(Passphrase passphrase) {
|
|
|
|
PGPSecretKeyRing trustRoot;
|
|
|
|
KeyRingBuilder builder = PGPainless.buildKeyRing()
|
|
|
|
.addUserId("trust-root");
|
|
|
|
if (passphrase != null) {
|
|
|
|
builder.setPassphrase(passphrase);
|
|
|
|
}
|
|
|
|
builder.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER));
|
|
|
|
try {
|
|
|
|
trustRoot = builder.build();
|
|
|
|
} catch (NoSuchAlgorithmException | PGPException | InvalidAlgorithmParameterException e) {
|
|
|
|
throw new RuntimeException("Cannot generate trust-root OpenPGP key", e);
|
|
|
|
}
|
|
|
|
return trustRoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
private PGPSecretKeyRing readTrustRoot(InputStream inputStream) {
|
|
|
|
try {
|
|
|
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(inputStream);
|
|
|
|
if (secretKeys == null) {
|
|
|
|
throw new BadDataException();
|
|
|
|
}
|
|
|
|
return secretKeys;
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new RuntimeException("Cannot read trust-root OpenPGP key", e);
|
|
|
|
} catch (BadDataException e) {
|
|
|
|
throw new RuntimeException("trust-root does not contain OpenPGP key", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|