mirror of
https://codeberg.org/PGPainless/sop-java.git
synced 2025-09-11 11:19:45 +02:00
Compare commits
No commits in common. "ced207382cd1c510f6c97f51c50c3eae4e787df2" and "1084cf6128375c2ff2a2cdef352adfd359b108bd" have entirely different histories.
ced207382c
...
1084cf6128
12 changed files with 42 additions and 280 deletions
29
.reuse/dep5
Normal file
29
.reuse/dep5
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: SOP-Java
|
||||||
|
Upstream-Contact: Paul Schaub <info@pgpainless.org>
|
||||||
|
Source: https://pgpainless.org
|
||||||
|
|
||||||
|
# Sample paragraph, commented out:
|
||||||
|
#
|
||||||
|
# Files: src/*
|
||||||
|
# Copyright: $YEAR $NAME <$CONTACT>
|
||||||
|
# License: ...
|
||||||
|
|
||||||
|
# Gradle build tool
|
||||||
|
Files: gradle*
|
||||||
|
Copyright: 2015 the original author or authors.
|
||||||
|
License: Apache-2.0
|
||||||
|
|
||||||
|
# Woodpecker build files
|
||||||
|
Files: .woodpecker/*
|
||||||
|
Copyright: 2022 the original author or authors.
|
||||||
|
License: Apache-2.0
|
||||||
|
|
||||||
|
Files: external-sop/src/main/resources/sop/testsuite/external/*
|
||||||
|
Copyright: 2023 the original author or authors
|
||||||
|
License: Apache-2.0
|
||||||
|
|
||||||
|
# Github Issue Templates
|
||||||
|
Files: .github/ISSUE_TEMPLATE/*
|
||||||
|
Copyright: 2024 the original author or authors
|
||||||
|
License: Apache-2.0
|
32
REUSE.toml
32
REUSE.toml
|
@ -1,32 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2025 Paul Schaub <info@pgpainless.org>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
|
||||||
|
|
||||||
version = 1
|
|
||||||
SPDX-PackageName = "SOP-Java"
|
|
||||||
SPDX-PackageSupplier = "Paul Schaub <info@pgpainless.org>"
|
|
||||||
SPDX-PackageDownloadLocation = "https://pgpainless.org"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "gradle**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2015 the original author or authors."
|
|
||||||
SPDX-License-Identifier = "Apache-2.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ".woodpecker/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2022 the original author or authors."
|
|
||||||
SPDX-License-Identifier = "Apache-2.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "external-sop/src/main/resources/sop/testsuite/external/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2023 the original author or authors"
|
|
||||||
SPDX-License-Identifier = "Apache-2.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ".github/ISSUE_TEMPLATE/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2024 the original author or authors"
|
|
||||||
SPDX-License-Identifier = "Apache-2.0"
|
|
|
@ -21,7 +21,7 @@ class UpdateKeyExternal(binary: String, environment: Properties) : UpdateKey {
|
||||||
|
|
||||||
override fun signingOnly(): UpdateKey = apply { commandList.add("--signing-only") }
|
override fun signingOnly(): UpdateKey = apply { commandList.add("--signing-only") }
|
||||||
|
|
||||||
override fun noAddedCapabilities(): UpdateKey = apply { commandList.add("--no-added-capabilities") }
|
override fun noNewMechanisms(): UpdateKey = apply { commandList.add("--no-new-mechanisms") }
|
||||||
|
|
||||||
override fun withKeyPassword(password: ByteArray): UpdateKey = apply {
|
override fun withKeyPassword(password: ByteArray): UpdateKey = apply {
|
||||||
commandList.add("--with-key-password=@ENV:KEY_PASSWORD_$argCount")
|
commandList.add("--with-key-password=@ENV:KEY_PASSWORD_$argCount")
|
||||||
|
|
|
@ -88,10 +88,7 @@ class SopCLI {
|
||||||
// Hide generate-completion command
|
// Hide generate-completion command
|
||||||
subcommands["generate-completion"]?.commandSpec?.usageMessage()?.hidden(true)
|
subcommands["generate-completion"]?.commandSpec?.usageMessage()?.hidden(true)
|
||||||
// render Input/Output sections in help command
|
// render Input/Output sections in help command
|
||||||
subcommands.values
|
subcommands.values.filter { (it.getCommand() as Any) is AbstractSopCmd } // Only for AbstractSopCmd objects
|
||||||
.filter {
|
|
||||||
(it.getCommand() as Any) is AbstractSopCmd
|
|
||||||
} // Only for AbstractSopCmd objects
|
|
||||||
.forEach { (it.getCommand() as AbstractSopCmd).installIORenderer(it) }
|
.forEach { (it.getCommand() as AbstractSopCmd).installIORenderer(it) }
|
||||||
// overwrite executable name
|
// overwrite executable name
|
||||||
commandName = EXECUTABLE_NAME
|
commandName = EXECUTABLE_NAME
|
||||||
|
@ -99,8 +96,7 @@ class SopCLI {
|
||||||
executionExceptionHandler = SOPExecutionExceptionHandler()
|
executionExceptionHandler = SOPExecutionExceptionHandler()
|
||||||
exitCodeExceptionMapper = SOPExceptionExitCodeMapper()
|
exitCodeExceptionMapper = SOPExceptionExitCodeMapper()
|
||||||
isCaseInsensitiveEnumValuesAllowed = true
|
isCaseInsensitiveEnumValuesAllowed = true
|
||||||
}
|
}.execute(*args)
|
||||||
.execute(*args)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import sop.exception.SOPGPException
|
||||||
exitCodeOnInvalidInput = SOPGPException.UnsupportedOption.EXIT_CODE)
|
exitCodeOnInvalidInput = SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||||
class MergeCertsCmd : AbstractSopCmd() {
|
class MergeCertsCmd : AbstractSopCmd() {
|
||||||
|
|
||||||
@CommandLine.Option(names = ["--no-armor"], negatable = true) var armor = true
|
@CommandLine.Option(names = ["--no-armor"], negatable = true) var armor = false
|
||||||
|
|
||||||
@CommandLine.Parameters(paramLabel = "CERTS") var updates: List<String> = listOf()
|
@CommandLine.Parameters(paramLabel = "CERTS") var updates: List<String> = listOf()
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class UpdateKeyCmd : AbstractSopCmd() {
|
||||||
|
|
||||||
@Option(names = ["--signing-only"]) var signingOnly = false
|
@Option(names = ["--signing-only"]) var signingOnly = false
|
||||||
|
|
||||||
@Option(names = ["--no-added-capabilities"]) var noAddedCapabilities = false
|
@Option(names = ["--no-new-mechanisms"]) var noNewMechanisms = false
|
||||||
|
|
||||||
@Option(names = ["--with-key-password"], paramLabel = "PASSWORD")
|
@Option(names = ["--with-key-password"], paramLabel = "PASSWORD")
|
||||||
var withKeyPassword: List<String> = listOf()
|
var withKeyPassword: List<String> = listOf()
|
||||||
|
@ -38,8 +38,8 @@ class UpdateKeyCmd : AbstractSopCmd() {
|
||||||
updateKey.signingOnly()
|
updateKey.signingOnly()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noAddedCapabilities) {
|
if (noNewMechanisms) {
|
||||||
updateKey.noAddedCapabilities()
|
updateKey.noNewMechanisms()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (passwordFileName in withKeyPassword) {
|
for (passwordFileName in withKeyPassword) {
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
package sop.cli.picocli.commands
|
package sop.cli.picocli.commands
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
|
||||||
import picocli.CommandLine.Command
|
import picocli.CommandLine.Command
|
||||||
import picocli.CommandLine.Option
|
import picocli.CommandLine.Option
|
||||||
import picocli.CommandLine.Parameters
|
import picocli.CommandLine.Parameters
|
||||||
import sop.cli.picocli.SopCLI
|
import sop.cli.picocli.SopCLI
|
||||||
import sop.exception.SOPGPException
|
import sop.exception.SOPGPException
|
||||||
import sop.util.HexUtil.Companion.bytesToHex
|
import sop.util.HexUtil.Companion.bytesToHex
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
name = "validate-userid",
|
name = "validate-userid",
|
||||||
|
|
|
@ -1,153 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package sop.testsuite.operation;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.condition.EnabledIf;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
|
||||||
import sop.SOP;
|
|
||||||
import sop.exception.SOPGPException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends")
|
|
||||||
public class CertifyValidateUserIdTest {
|
|
||||||
|
|
||||||
static Stream<Arguments> provideInstances() {
|
|
||||||
return AbstractSOPTest.provideBackends();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("provideInstances")
|
|
||||||
public void certifyUserId(SOP sop) throws IOException {
|
|
||||||
byte[] aliceKey = sop.generateKey()
|
|
||||||
.withKeyPassword("sw0rdf1sh")
|
|
||||||
.userId("Alice <alice@pgpainless.org>")
|
|
||||||
.generate()
|
|
||||||
.getBytes();
|
|
||||||
byte[] aliceCert = sop.extractCert()
|
|
||||||
.key(aliceKey)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
byte[] bobKey = sop.generateKey()
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.generate()
|
|
||||||
.getBytes();
|
|
||||||
byte[] bobCert = sop.extractCert()
|
|
||||||
.key(bobKey)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
// Alice has her own user-id self-certified
|
|
||||||
assertTrue(sop.validateUserId()
|
|
||||||
.authorities(aliceCert)
|
|
||||||
.userId("Alice <alice@pgpainless.org>")
|
|
||||||
.subjects(aliceCert),
|
|
||||||
"Alice accepts her own self-certified user-id");
|
|
||||||
|
|
||||||
// Alice has not yet certified Bobs user-id
|
|
||||||
assertFalse(sop.validateUserId()
|
|
||||||
.authorities(aliceCert)
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.subjects(bobCert),
|
|
||||||
"Alice has not yet certified Bobs user-id");
|
|
||||||
|
|
||||||
byte[] bobCertifiedByAlice = sop.certifyUserId()
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.withKeyPassword("sw0rdf1sh")
|
|
||||||
.keys(aliceKey)
|
|
||||||
.certs(bobCert)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
assertTrue(sop.validateUserId()
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.authorities(aliceCert)
|
|
||||||
.subjects(bobCertifiedByAlice),
|
|
||||||
"Alice accepts Bobs user-id after she certified it");
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("provideInstances")
|
|
||||||
public void addPetName(SOP sop) throws IOException {
|
|
||||||
byte[] aliceKey = sop.generateKey()
|
|
||||||
.userId("Alice <alice@pgpainless.org>")
|
|
||||||
.generate()
|
|
||||||
.getBytes();
|
|
||||||
byte[] aliceCert = sop.extractCert()
|
|
||||||
.key(aliceKey)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
byte[] bobKey = sop.generateKey()
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.generate()
|
|
||||||
.getBytes();
|
|
||||||
byte[] bobCert = sop.extractCert()
|
|
||||||
.key(bobKey)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
assertThrows(SOPGPException.CertUserIdNoMatch.class, () ->
|
|
||||||
sop.certifyUserId()
|
|
||||||
.userId("Bobby")
|
|
||||||
.keys(aliceKey)
|
|
||||||
.certs(bobCert)
|
|
||||||
.getBytes(),
|
|
||||||
"Alice cannot create a pet-name for Bob without the --no-require-self-sig flag");
|
|
||||||
|
|
||||||
byte[] bobWithPetName = sop.certifyUserId()
|
|
||||||
.userId("Bobby")
|
|
||||||
.noRequireSelfSig()
|
|
||||||
.keys(aliceKey)
|
|
||||||
.certs(bobCert)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
assertTrue(sop.validateUserId()
|
|
||||||
.userId("Bobby")
|
|
||||||
.authorities(aliceCert)
|
|
||||||
.subjects(bobWithPetName),
|
|
||||||
"Alice accepts the pet-name she gave to Bob");
|
|
||||||
|
|
||||||
assertFalse(sop.validateUserId()
|
|
||||||
.userId("Bobby")
|
|
||||||
.authorities(bobWithPetName)
|
|
||||||
.subjects(bobWithPetName),
|
|
||||||
"Bob does not accept the pet-name Alice gave him");
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("provideInstances")
|
|
||||||
public void certifyWithRevokedKey(SOP sop) throws IOException {
|
|
||||||
byte[] aliceKey = sop.generateKey()
|
|
||||||
.userId("Alice <alice@pgpainless.org>")
|
|
||||||
.generate()
|
|
||||||
.getBytes();
|
|
||||||
byte[] aliceRevokedCert = sop.revokeKey()
|
|
||||||
.keys(aliceKey)
|
|
||||||
.getBytes();
|
|
||||||
byte[] aliceRevokedKey = sop.updateKey()
|
|
||||||
.mergeCerts(aliceRevokedCert)
|
|
||||||
.key(aliceKey)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
byte[] bobKey = sop.generateKey()
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.generate()
|
|
||||||
.getBytes();
|
|
||||||
byte[] bobCert = sop.extractCert()
|
|
||||||
.key(bobKey)
|
|
||||||
.getBytes();
|
|
||||||
|
|
||||||
assertThrows(SOPGPException.KeyCannotCertify.class, () ->
|
|
||||||
sop.certifyUserId()
|
|
||||||
.userId("Bob <bob@pgpainless.org>")
|
|
||||||
.keys(aliceRevokedKey)
|
|
||||||
.certs(bobCert)
|
|
||||||
.getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,10 +9,9 @@ package sop
|
||||||
*
|
*
|
||||||
* @param micAlg string identifying the digest mechanism used to create the signed message. This is
|
* @param micAlg string identifying the digest mechanism used to create the signed message. This is
|
||||||
* useful for setting the `micalg=` parameter for the multipart/signed content-type of a PGP/MIME
|
* useful for setting the `micalg=` parameter for the multipart/signed content-type of a PGP/MIME
|
||||||
* object as described in section 5 of
|
* object as described in section 5 of [RFC3156](https://www.rfc-editor.org/rfc/rfc3156#section-5).
|
||||||
* [RFC3156](https://www.rfc-editor.org/rfc/rfc3156#section-5). If more than one signature was
|
* If more than one signature was generated and different digest mechanisms were used, the value
|
||||||
* generated and different digest mechanisms were used, the value of the micalg object is an empty
|
* of the micalg object is an empty string.
|
||||||
* string.
|
|
||||||
*/
|
*/
|
||||||
data class SigningResult(val micAlg: MicAlg) {
|
data class SigningResult(val micAlg: MicAlg) {
|
||||||
|
|
||||||
|
|
|
@ -16,22 +16,6 @@ abstract class SOPGPException : RuntimeException {
|
||||||
|
|
||||||
abstract fun getExitCode(): Int
|
abstract fun getExitCode(): Int
|
||||||
|
|
||||||
/** An otherwise unspecified failure occurred */
|
|
||||||
class UnspecificFailure : SOPGPException {
|
|
||||||
|
|
||||||
constructor(message: String) : super(message)
|
|
||||||
|
|
||||||
constructor(message: String, e: Throwable) : super(message, e)
|
|
||||||
|
|
||||||
constructor(e: Throwable) : super(e)
|
|
||||||
|
|
||||||
override fun getExitCode(): Int = EXIT_CODE
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val EXIT_CODE = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** No acceptable signatures found (sop verify, inline-verify). */
|
/** No acceptable signatures found (sop verify, inline-verify). */
|
||||||
class NoSignature : SOPGPException {
|
class NoSignature : SOPGPException {
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
|
@ -394,23 +378,4 @@ abstract class SOPGPException : RuntimeException {
|
||||||
const val EXIT_CODE = 107
|
const val EXIT_CODE = 107
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Key not certification-capable (e.g., expired, revoked, unacceptable usage flags) (sop
|
|
||||||
* certify-userid)
|
|
||||||
*/
|
|
||||||
class KeyCannotCertify : SOPGPException {
|
|
||||||
|
|
||||||
constructor(message: String) : super(message)
|
|
||||||
|
|
||||||
constructor(message: String, e: Throwable) : super(message, e)
|
|
||||||
|
|
||||||
constructor(e: Throwable) : super(e)
|
|
||||||
|
|
||||||
override fun getExitCode(): Int = EXIT_CODE
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val EXIT_CODE = 109
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,61 +19,25 @@ interface UpdateKey {
|
||||||
*/
|
*/
|
||||||
fun noArmor(): UpdateKey
|
fun noArmor(): UpdateKey
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow key to be used for signing only.
|
|
||||||
* If this option is not present, the operation may add a new, encryption-capable component key.
|
|
||||||
*/
|
|
||||||
@Throws(SOPGPException.UnsupportedOption::class) fun signingOnly(): UpdateKey
|
@Throws(SOPGPException.UnsupportedOption::class) fun signingOnly(): UpdateKey
|
||||||
|
|
||||||
/**
|
@Throws(SOPGPException.UnsupportedOption::class) fun noNewMechanisms(): UpdateKey
|
||||||
* Do not allow adding new capabilities to the key.
|
|
||||||
* If this option is not present, the operation may add support for new capabilities to the key.
|
|
||||||
*/
|
|
||||||
@Throws(SOPGPException.UnsupportedOption::class) fun noAddedCapabilities(): UpdateKey
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a passphrase for unlocking the secret key.
|
|
||||||
*
|
|
||||||
* @param password password
|
|
||||||
*/
|
|
||||||
@Throws(SOPGPException.PasswordNotHumanReadable::class, SOPGPException.UnsupportedOption::class)
|
@Throws(SOPGPException.PasswordNotHumanReadable::class, SOPGPException.UnsupportedOption::class)
|
||||||
fun withKeyPassword(password: String): UpdateKey =
|
fun withKeyPassword(password: String): UpdateKey =
|
||||||
withKeyPassword(password.toByteArray(UTF8Util.UTF8))
|
withKeyPassword(password.toByteArray(UTF8Util.UTF8))
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a passphrase for unlocking the secret key.
|
|
||||||
*
|
|
||||||
* @param password password
|
|
||||||
*/
|
|
||||||
@Throws(SOPGPException.PasswordNotHumanReadable::class, SOPGPException.UnsupportedOption::class)
|
@Throws(SOPGPException.PasswordNotHumanReadable::class, SOPGPException.UnsupportedOption::class)
|
||||||
fun withKeyPassword(password: ByteArray): UpdateKey
|
fun withKeyPassword(password: ByteArray): UpdateKey
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide certificates that might contain updated signatures or third-party certifications.
|
|
||||||
* These certificates will be merged into the key.
|
|
||||||
*
|
|
||||||
* @param certs input stream of certificates
|
|
||||||
*/
|
|
||||||
@Throws(
|
@Throws(
|
||||||
SOPGPException.UnsupportedOption::class, SOPGPException.BadData::class, IOException::class)
|
SOPGPException.UnsupportedOption::class, SOPGPException.BadData::class, IOException::class)
|
||||||
fun mergeCerts(certs: InputStream): UpdateKey
|
fun mergeCerts(certs: InputStream): UpdateKey
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide certificates that might contain updated signatures or third-party certifications.
|
|
||||||
* These certificates will be merged into the key.
|
|
||||||
*
|
|
||||||
* @param certs binary certificates
|
|
||||||
*/
|
|
||||||
@Throws(
|
@Throws(
|
||||||
SOPGPException.UnsupportedOption::class, SOPGPException.BadData::class, IOException::class)
|
SOPGPException.UnsupportedOption::class, SOPGPException.BadData::class, IOException::class)
|
||||||
fun mergeCerts(certs: ByteArray): UpdateKey = mergeCerts(certs.inputStream())
|
fun mergeCerts(certs: ByteArray): UpdateKey = mergeCerts(certs.inputStream())
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide the OpenPGP key to update.
|
|
||||||
*
|
|
||||||
* @param key input stream containing the key
|
|
||||||
* @return handle to acquire the updated OpenPGP key from
|
|
||||||
*/
|
|
||||||
@Throws(
|
@Throws(
|
||||||
SOPGPException.BadData::class,
|
SOPGPException.BadData::class,
|
||||||
IOException::class,
|
IOException::class,
|
||||||
|
@ -81,12 +45,6 @@ interface UpdateKey {
|
||||||
SOPGPException.PrimaryKeyBad::class)
|
SOPGPException.PrimaryKeyBad::class)
|
||||||
fun key(key: InputStream): Ready
|
fun key(key: InputStream): Ready
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide the OpenPGP key to update.
|
|
||||||
*
|
|
||||||
* @param key binary OpenPGP key
|
|
||||||
* @return handle to acquire the updated OpenPGP key from
|
|
||||||
*/
|
|
||||||
@Throws(
|
@Throws(
|
||||||
SOPGPException.BadData::class,
|
SOPGPException.BadData::class,
|
||||||
IOException::class,
|
IOException::class,
|
||||||
|
|
|
@ -6,8 +6,8 @@ package sop.operation
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.*
|
|
||||||
import sop.exception.SOPGPException
|
import sop.exception.SOPGPException
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/** Subcommand to validate UserIDs on certificates. */
|
/** Subcommand to validate UserIDs on certificates. */
|
||||||
interface ValidateUserId {
|
interface ValidateUserId {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue