diff --git a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt index 056aa27..3aa5fee 100644 --- a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt +++ b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt @@ -28,6 +28,7 @@ import sop.exception.SOPGPException RevokeKeyCmd::class, ExtractCertCmd::class, UpdateKeyCmd::class, + MergeCertsCmd::class, // Messaging subcommands SignCmd::class, VerifyCmd::class, diff --git a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/commands/MergeCertsCmd.kt b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/commands/MergeCertsCmd.kt new file mode 100644 index 0000000..15b33f8 --- /dev/null +++ b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/commands/MergeCertsCmd.kt @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2024 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package sop.cli.picocli.commands + +import picocli.CommandLine +import picocli.CommandLine.Command +import sop.cli.picocli.SopCLI +import sop.exception.SOPGPException +import java.io.IOException + +@Command( + name = "merge-certs", + resourceBundle = "msg_merge-certs", + exitCodeOnInvalidInput = SOPGPException.UnsupportedOption.EXIT_CODE) +class MergeCertsCmd : AbstractSopCmd() { + + @CommandLine.Option(names = ["--no-armor"], negatable = true) + var armor = false + + @CommandLine.Parameters(paramLabel = "CERTS") + var updates: List = listOf() + + override fun run() { + val mergeCerts = throwIfUnsupportedSubcommand(SopCLI.getSop().mergeCerts(), "merge-certs") + + if (!armor) { + mergeCerts.noArmor() + } + + for (certFileName in updates) { + try { + getInput(certFileName).use { mergeCerts.updates(it) } + } catch (e: IOException) { + throw RuntimeException(e) + } + } + + try { + + val ready = mergeCerts.baseCertificates(System.`in`) + ready.writeTo(System.out) + } catch (e: IOException) { + throw RuntimeException(e) + } + } +} \ No newline at end of file diff --git a/sop-java-picocli/src/main/resources/msg_merge-certs.properties b/sop-java-picocli/src/main/resources/msg_merge-certs.properties new file mode 100644 index 0000000..866db4b --- /dev/null +++ b/sop-java-picocli/src/main/resources/msg_merge-certs.properties @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2024 Paul Schaub +# +# SPDX-License-Identifier: Apache-2.0 +usage.headerHeading=Merge OpenPGP certificates%n +usage.description=BLABLA +no-armor=ASCII armor the output +CERTS[0..*]=OpenPGP certificates from which updates shall be merged into the base certificates from standard input + +stacktrace=Print stacktrace +# Generic TODO: Remove when bumping picocli to 4.7.0 +usage.parameterListHeading=%nParameters:%n +usage.synopsisHeading=Usage:\u0020 +usage.commandListHeading = %nCommands:%n +usage.optionListHeading = %nOptions:%n +usage.footerHeading=Powered by picocli%n diff --git a/sop-java-picocli/src/main/resources/msg_merge-certs_de.properties b/sop-java-picocli/src/main/resources/msg_merge-certs_de.properties new file mode 100644 index 0000000..021c535 --- /dev/null +++ b/sop-java-picocli/src/main/resources/msg_merge-certs_de.properties @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2024 Paul Schaub +# +# SPDX-License-Identifier: Apache-2.0 +usage.headerHeading=OpenPGP Zertifikate zusammenführen%n%n +usage.header=Führe OpenPGP Zertifikate aus der Standardeingabe mit ensprechenden Elementen aus CERTS zusammen und gebe das Ergebnis auf der Standardausgabe aus +usage.description=Es werden nur Zertifikate auf die Standardausgabe geschrieben, welche Teil der Standardeingabe waren +no-armor=Schütze Ausgabe mit ASCII Armor +CERTS[0..*]=OpenPGP Zertifikate aus denen neue Elemente in die Basiszertifikate aus der Standardeingabe übernommen werden sollen + +usage.parameterList.0=STANDARDIN +usage.parameterList.1=STANDARDOUT + +# Generic TODO: Remove when bumping picocli to 4.7.0 +usage.parameterListHeading=%nParameter:%n +usage.synopsisHeading=Aufruf:\u0020 +usage.descriptionHeading=%nHinweise:%n +usage.commandListHeading=%nBefehle:%n +usage.optionListHeading = %nOptionen:%n +usage.footerHeading=Powered by Picocli%n diff --git a/sop-java/src/main/kotlin/sop/SOP.kt b/sop-java/src/main/kotlin/sop/SOP.kt index c53bb7d..1640d5f 100644 --- a/sop-java/src/main/kotlin/sop/SOP.kt +++ b/sop-java/src/main/kotlin/sop/SOP.kt @@ -64,4 +64,9 @@ interface SOP : SOPV { * Keep a secret key up-to-date. */ fun updateKey(): UpdateKey + + /** + * Merge OpenPGP certificates. + */ + fun mergeCerts(): MergeCerts } diff --git a/sop-java/src/main/kotlin/sop/operation/MergeCerts.kt b/sop-java/src/main/kotlin/sop/operation/MergeCerts.kt new file mode 100644 index 0000000..f60d291 --- /dev/null +++ b/sop-java/src/main/kotlin/sop/operation/MergeCerts.kt @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2024 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package sop.operation + +import sop.Ready +import sop.exception.SOPGPException +import java.io.IOException +import java.io.InputStream + +interface MergeCerts { + + @Throws(SOPGPException.UnsupportedOption::class) + fun noArmor(): MergeCerts + + @Throws(SOPGPException.BadData::class, IOException::class) + fun updates(updateCerts: InputStream): MergeCerts + + @Throws(SOPGPException.BadData::class, IOException::class) + fun updates(updateCerts: ByteArray): MergeCerts = updates(updateCerts.inputStream()) + + @Throws(SOPGPException.BadData::class, IOException::class) + fun baseCertificates(certs: InputStream): Ready + + @Throws(SOPGPException.BadData::class, IOException::class) + fun baseCertificates(certs: ByteArray): Ready = baseCertificates(certs.inputStream()) +} \ No newline at end of file