1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-10 02:39:39 +02:00

KeyRingInfo: Expose OpenPGPComponentKey in place of PGPPublicKey, OpenPGPSecretKey instead of PGPSecretKey

This commit is contained in:
Paul Schaub 2025-02-05 12:01:16 +01:00
parent 76ea97c6f4
commit 021b09dfb7
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
27 changed files with 254 additions and 248 deletions

View file

@ -252,7 +252,7 @@ public class RoundTripSignVerifyCmdTest extends CLITest {
String verification = verificationsOut.toString(); String verification = verificationsOut.toString();
String[] split = verification.split(" "); String[] split = verification.split(" ");
OpenPgpV4Fingerprint primaryKeyFingerprint = new OpenPgpV4Fingerprint(cert); OpenPgpV4Fingerprint primaryKeyFingerprint = new OpenPgpV4Fingerprint(cert);
OpenPgpV4Fingerprint signingKeyFingerprint = new OpenPgpV4Fingerprint(info.getSigningSubkeys().get(0)); OpenPgpV4Fingerprint signingKeyFingerprint = new OpenPgpV4Fingerprint(info.getSigningSubkeys().get(0).getPGPPublicKey());
assertEquals(signingKeyFingerprint.toString(), split[1].trim(), verification); assertEquals(signingKeyFingerprint.toString(), split[1].trim(), verification);
assertEquals(primaryKeyFingerprint.toString(), split[2].trim()); assertEquals(primaryKeyFingerprint.toString(), split[2].trim());

View file

@ -675,17 +675,17 @@ class OpenPgpMessageInputStream(
private fun getDecryptionKey(keyId: Long): PGPSecretKeyRing? = private fun getDecryptionKey(keyId: Long): PGPSecretKeyRing? =
options.getDecryptionKeys().firstOrNull { options.getDecryptionKeys().firstOrNull {
it.any { k -> k.keyID == keyId } it.any { k -> k.keyID == keyId }
.and(PGPainless.inspectKeyRing(it).decryptionSubkeys.any { k -> k.keyID == keyId }) .and(
PGPainless.inspectKeyRing(it).decryptionSubkeys.any { k ->
k.keyIdentifier.keyId == keyId
})
} }
private fun getDecryptionKey(pkesk: PGPPublicKeyEncryptedData): PGPSecretKeyRing? = private fun getDecryptionKey(pkesk: PGPPublicKeyEncryptedData): PGPSecretKeyRing? =
options.getDecryptionKeys().firstOrNull { options.getDecryptionKeys().firstOrNull {
it.getSecretKeyFor(pkesk) != null && it.getSecretKeyFor(pkesk) != null &&
PGPainless.inspectKeyRing(it).decryptionSubkeys.any { subkey -> PGPainless.inspectKeyRing(it).decryptionSubkeys.any { subkey ->
when (pkesk.version) { pkesk.keyIdentifier.matches(subkey.keyIdentifier)
3 -> pkesk.keyID == subkey.keyID
else -> throw NotImplementedError("Version 6 PKESK not yet supported.")
}
} }
} }
@ -693,10 +693,7 @@ class OpenPgpMessageInputStream(
options.getDecryptionKeys().filter { options.getDecryptionKeys().filter {
it.getSecretKeyFor(pkesk) != null && it.getSecretKeyFor(pkesk) != null &&
PGPainless.inspectKeyRing(it).decryptionSubkeys.any { subkey -> PGPainless.inspectKeyRing(it).decryptionSubkeys.any { subkey ->
when (pkesk.version) { pkesk.keyIdentifier.matches(subkey.keyIdentifier)
3 -> pkesk.keyID == subkey.keyID
else -> throw NotImplementedError("Version 6 PKESK not yet supported.")
}
} }
} }
@ -708,8 +705,9 @@ class OpenPgpMessageInputStream(
options.getDecryptionKeys().forEach { options.getDecryptionKeys().forEach {
val info = PGPainless.inspectKeyRing(it) val info = PGPainless.inspectKeyRing(it)
for (key in info.decryptionSubkeys) { for (key in info.decryptionSubkeys) {
if (key.algorithm == algorithm && info.isSecretKeyAvailable(key.keyID)) { if (key.pgpPublicKey.algorithm == algorithm &&
candidates.add(it to it.getSecretKey(key.keyID)) info.isSecretKeyAvailable(key.keyIdentifier)) {
candidates.add(it to it.getSecretKey(key.keyIdentifier))
} }
} }
} }

View file

@ -27,9 +27,11 @@ class BcHashContextSigner {
): PGPSignature { ): PGPSignature {
val info = PGPainless.inspectKeyRing(secretKey) val info = PGPainless.inspectKeyRing(secretKey)
return info.signingSubkeys return info.signingSubkeys
.mapNotNull { info.getSecretKey(it.keyID) } .mapNotNull { info.getSecretKey(it.keyIdentifier) }
.firstOrNull() .firstOrNull()
?.let { signHashContext(hashContext, signatureType, it.unlock(protector)) } ?.let {
signHashContext(hashContext, signatureType, it.pgpSecretKey.unlock(protector))
}
?: throw PGPException("Key does not contain suitable signing subkey.") ?: throw PGPException("Key does not contain suitable signing subkey.")
} }

View file

@ -144,7 +144,7 @@ class EncryptionOptions(private val purpose: EncryptionPurpose) {
val info = KeyRingInfo(key, evaluationDate) val info = KeyRingInfo(key, evaluationDate)
val subkeys = val subkeys =
encryptionKeySelector.selectEncryptionSubkeys( encryptionKeySelector.selectEncryptionSubkeys(
info.getEncryptionSubkeys(userId, purpose)) info.getEncryptionSubkeys(userId, purpose).map { it.pgpPublicKey })
if (subkeys.isEmpty()) { if (subkeys.isEmpty()) {
throw KeyException.UnacceptableEncryptionKeyException(OpenPgpFingerprint.of(key)) throw KeyException.UnacceptableEncryptionKeyException(OpenPgpFingerprint.of(key))
} }
@ -184,7 +184,9 @@ class EncryptionOptions(private val purpose: EncryptionPurpose) {
throw ExpiredKeyException(OpenPgpFingerprint.of(key), primaryKeyExpiration) throw ExpiredKeyException(OpenPgpFingerprint.of(key), primaryKeyExpiration)
} }
var encryptionSubkeys = selector.selectEncryptionSubkeys(info.getEncryptionSubkeys(purpose)) var encryptionSubkeys =
selector.selectEncryptionSubkeys(
info.getEncryptionSubkeys(purpose).map { it.pgpPublicKey })
// There are some legacy keys around without key flags. // There are some legacy keys around without key flags.
// If we allow encryption for those keys, we add valid keys without any key flags, if they // If we allow encryption for those keys, we add valid keys without any key flags, if they
@ -193,8 +195,9 @@ class EncryptionOptions(private val purpose: EncryptionPurpose) {
if (encryptionSubkeys.isEmpty() && allowEncryptionWithMissingKeyFlags) { if (encryptionSubkeys.isEmpty() && allowEncryptionWithMissingKeyFlags) {
encryptionSubkeys = encryptionSubkeys =
info.validSubkeys info.validSubkeys
.filter { it.isEncryptionKey } .filter { it.pgpPublicKey.isEncryptionKey }
.filter { info.getKeyFlagsOf(it.keyID).isEmpty() } .filter { info.getKeyFlagsOf(it.keyIdentifier).isEmpty() }
.map { it.pgpPublicKey }
} }
if (encryptionSubkeys.isEmpty()) { if (encryptionSubkeys.isEmpty()) {

View file

@ -5,6 +5,7 @@
package org.pgpainless.encryption_signing package org.pgpainless.encryption_signing
import java.util.* import java.util.*
import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.pgpainless.PGPainless.Companion.getPolicy import org.pgpainless.PGPainless.Companion.getPolicy
import org.pgpainless.PGPainless.Companion.inspectKeyRing import org.pgpainless.PGPainless.Companion.inspectKeyRing
@ -153,12 +154,13 @@ class SigningOptions {
for (signingPubKey in signingPubKeys) { for (signingPubKey in signingPubKeys) {
val signingSecKey: PGPSecretKey = val signingSecKey: PGPSecretKey =
signingKey.getSecretKey(signingPubKey.keyID) signingKey.getSecretKey(signingPubKey.keyIdentifier)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(
of(signingKey), signingPubKey.keyIdentifier.keyId)
val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector) val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = val hashAlgorithms =
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId) if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy()) val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
addSigningMethod( addSigningMethod(
signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback) signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback)
@ -197,15 +199,16 @@ class SigningOptions {
} }
for (signingPubKey in signingPubKeys) { for (signingPubKey in signingPubKeys) {
if (signingPubKey.keyID != keyId) { if (!signingPubKey.keyIdentifier.matches(KeyIdentifier(keyId))) {
continue continue
} }
val signingSecKey = val signingSecKey =
signingKey.getSecretKey(signingPubKey.keyID) signingKey.getSecretKey(signingPubKey.keyIdentifier)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(
of(signingKey), signingPubKey.keyIdentifier.keyId)
val signingSubkey = signingSecKey.unlock(signingKeyProtector) val signingSubkey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy()) val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
addSigningMethod( addSigningMethod(
signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback) signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback)
@ -297,12 +300,13 @@ class SigningOptions {
for (signingPubKey in signingPubKeys) { for (signingPubKey in signingPubKeys) {
val signingSecKey: PGPSecretKey = val signingSecKey: PGPSecretKey =
signingKey.getSecretKey(signingPubKey.keyID) signingKey.getSecretKey(signingPubKey.keyIdentifier)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(
of(signingKey), signingPubKey.keyIdentifier.keyId)
val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector) val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = val hashAlgorithms =
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId) if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy()) val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
addSigningMethod( addSigningMethod(
signingKey, signingSubkey, hashAlgorithm, signatureType, true, subpacketCallback) signingKey, signingSubkey, hashAlgorithm, signatureType, true, subpacketCallback)
@ -342,12 +346,14 @@ class SigningOptions {
} }
for (signingPubKey in signingPubKeys) { for (signingPubKey in signingPubKeys) {
if (signingPubKey.keyID == keyId) { if (signingPubKey.keyIdentifier.matches(KeyIdentifier(keyId))) {
val signingSecKey: PGPSecretKey = val signingSecKey: PGPSecretKey =
signingKey.getSecretKey(signingPubKey.keyID) signingKey.getSecretKey(signingPubKey.keyIdentifier)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(
of(signingKey), signingPubKey.keyIdentifier.keyId)
val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector) val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) val hashAlgorithms =
keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = val hashAlgorithm: HashAlgorithm =
negotiateHashAlgorithm(hashAlgorithms, getPolicy()) negotiateHashAlgorithm(hashAlgorithms, getPolicy())
addSigningMethod( addSigningMethod(

View file

@ -4,7 +4,6 @@
package org.pgpainless.key package org.pgpainless.key
import openpgp.openPgpKeyId
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPKeyRing import org.bouncycastle.openpgp.PGPKeyRing
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
@ -24,21 +23,23 @@ class SubkeyIdentifier(
constructor(key: PGPPublicKey) : this(OpenPgpFingerprint.of(key)) constructor(key: PGPPublicKey) : this(OpenPgpFingerprint.of(key))
constructor( constructor(keys: PGPKeyRing, keyId: Long) : this(keys, KeyIdentifier(keyId))
keys: PGPKeyRing,
keyId: Long
) : this(
OpenPgpFingerprint.of(keys.publicKey),
OpenPgpFingerprint.of(
keys.getPublicKey(keyId)
?: throw NoSuchElementException(
"OpenPGP key does not contain subkey ${keyId.openPgpKeyId()}")))
constructor( constructor(
keys: PGPKeyRing, keys: PGPKeyRing,
subkeyFingerprint: OpenPgpFingerprint subkeyFingerprint: OpenPgpFingerprint
) : this(OpenPgpFingerprint.of(keys), subkeyFingerprint) ) : this(OpenPgpFingerprint.of(keys), subkeyFingerprint)
constructor(
keys: PGPKeyRing,
subkeyIdentifier: KeyIdentifier
) : this(
OpenPgpFingerprint.of(keys),
OpenPgpFingerprint.of(
keys.getPublicKey(subkeyIdentifier)
?: throw NoSuchElementException(
"OpenPGP key does not contain subkey $subkeyIdentifier")))
val keyIdentifier = KeyIdentifier(subkeyFingerprint.bytes) val keyIdentifier = KeyIdentifier(subkeyFingerprint.bytes)
val subkeyIdentifier = keyIdentifier val subkeyIdentifier = keyIdentifier
val primaryKeyIdentifier = KeyIdentifier(primaryKeyFingerprint.bytes) val primaryKeyIdentifier = KeyIdentifier(primaryKeyFingerprint.bytes)

View file

@ -225,7 +225,7 @@ class CertifyCertificate {
val fingerprint = info.fingerprint val fingerprint = info.fingerprint
val certificationPubKey = info.getPublicKey(fingerprint) val certificationPubKey = info.getPublicKey(fingerprint)
requireNotNull(certificationPubKey) { "Primary key cannot be null." } requireNotNull(certificationPubKey) { "Primary key cannot be null." }
if (!info.isKeyValidlyBound(certificationPubKey.keyID)) { if (!info.isKeyValidlyBound(certificationPubKey.keyIdentifier)) {
throw RevokedKeyException(fingerprint) throw RevokedKeyException(fingerprint)
} }
@ -238,8 +238,9 @@ class CertifyCertificate {
throw ExpiredKeyException(fingerprint, expirationDate) throw ExpiredKeyException(fingerprint, expirationDate)
} }
return certificationKey.getSecretKey(certificationPubKey.keyID) return certificationKey.getSecretKey(certificationPubKey.keyIdentifier)
?: throw MissingSecretKeyException(fingerprint, certificationPubKey.keyID) ?: throw MissingSecretKeyException(
fingerprint, certificationPubKey.keyIdentifier.keyId)
} }
} }
} }

View file

@ -9,6 +9,9 @@ import openpgp.openPgpKeyId
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPCertificate import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.algorithm.* import org.pgpainless.algorithm.*
import org.pgpainless.bouncycastle.extensions.* import org.pgpainless.bouncycastle.extensions.*
@ -33,7 +36,10 @@ class KeyRingInfo(
keys: PGPKeyRing, keys: PGPKeyRing,
policy: Policy = PGPainless.getPolicy(), policy: Policy = PGPainless.getPolicy(),
referenceDate: Date = Date() referenceDate: Date = Date()
) : this(OpenPGPCertificate(keys), policy, referenceDate) ) : this(
if (keys is PGPSecretKeyRing) OpenPGPKey(keys) else OpenPGPCertificate(keys),
policy,
referenceDate)
@JvmOverloads @JvmOverloads
constructor( constructor(
@ -74,35 +80,32 @@ class KeyRingInfo(
if (revocationState.isSoftRevocation()) revocationState.date else null if (revocationState.isSoftRevocation()) revocationState.date else null
/** /**
* Primary [PGPSecretKey] of this key ring or null if the key ring is not a [PGPSecretKeyRing]. * Primary [OpenPGPSecretKey] of this key ring or null if the key ring is not a [OpenPGPKey].
*/ */
val secretKey: PGPSecretKey? = val secretKey: OpenPGPSecretKey? =
when (keys.pgpKeyRing) { if (keys.isSecretKey) {
is PGPSecretKeyRing -> (keys.pgpKeyRing as PGPSecretKeyRing).secretKey!! (keys as OpenPGPKey).primarySecretKey
else -> null } else null
}
/** OpenPGP key version. */ /** OpenPGP key version. */
val version: Int = publicKey.version val version: Int = publicKey.version
/** /**
* Return all [PGPPublicKeys][PGPPublicKey] of this key ring. The first key in the list being * Return all [public component keys][OpenPGPComponentKey] of this key ring. The first key in
* the primary key. Note that the list is unmodifiable. * the list being the primary key. Note that the list is unmodifiable.
* *
* @return list of public keys * @return list of public keys
*/ */
val publicKeys: List<PGPPublicKey> = keys.pgpKeyRing.publicKeys.asSequence().toList() val publicKeys: List<OpenPGPComponentKey> = keys.keys
/** All secret keys. If the key ring is a [PGPPublicKeyRing], then return an empty list. */ /** All secret keys. If the key ring is not an [OpenPGPKey], then return an empty list. */
val secretKeys: List<PGPSecretKey> = val secretKeys: List<OpenPGPSecretKey> =
when (keys.pgpKeyRing) { if (keys.isSecretKey) {
is PGPSecretKeyRing -> (keys as OpenPGPKey).secretKeys.values.toList()
(keys.pgpKeyRing as PGPSecretKeyRing).secretKeys.asSequence().toList() } else listOf()
else -> listOf()
}
/** List of valid public subkeys. */ /** List of valid public component keys. */
val validSubkeys: List<PGPPublicKey> = keys.getValidKeys(referenceDate).map { it.pgpPublicKey } val validSubkeys: List<OpenPGPComponentKey> = keys.getValidKeys(referenceDate)
/** List of valid user-IDs. */ /** List of valid user-IDs. */
val validUserIds: List<String> = keys.getValidUserIds(referenceDate).map { it.userId } val validUserIds: List<String> = keys.getValidUserIds(referenceDate).map { it.userId }
@ -144,30 +147,32 @@ class KeyRingInfo(
/** Latest date at which the key was modified (either by adding a subkey or self-signature). */ /** Latest date at which the key was modified (either by adding a subkey or self-signature). */
val lastModified: Date = keys.lastModificationDate val lastModified: Date = keys.lastModificationDate
/** True, if the underlying keyring is a [PGPSecretKeyRing]. */ /** True, if the underlying key is a [OpenPGPKey]. */
val isSecretKey: Boolean = keys.pgpKeyRing is PGPSecretKeyRing val isSecretKey: Boolean = keys.isSecretKey
/** True, if there are no encrypted secret keys. */ /** True, if there are no encrypted secret keys. */
val isFullyDecrypted: Boolean = val isFullyDecrypted: Boolean =
!isSecretKey || secretKeys.all { it.hasDummyS2K() || it.isDecrypted() } !isSecretKey ||
secretKeys.all { it.pgpSecretKey.hasDummyS2K() || it.pgpSecretKey.isDecrypted() }
/** True, if there are only encrypted secret keys. */ /** True, if there are only encrypted secret keys. */
val isFullyEncrypted: Boolean = val isFullyEncrypted: Boolean =
isSecretKey && secretKeys.none { !it.hasDummyS2K() && it.isDecrypted() } isSecretKey &&
secretKeys.none { !it.pgpSecretKey.hasDummyS2K() && it.pgpSecretKey.isDecrypted() }
/** List of public keys, whose secret key counterparts can be used to decrypt messages. */ /** List of public keys, whose secret key counterparts can be used to decrypt messages. */
val decryptionSubkeys: List<PGPPublicKey> = val decryptionSubkeys: List<OpenPGPComponentKey> =
keys.pgpKeyRing.publicKeys keys.keys
.asSequence() .asSequence()
.filter { .filter {
if (!it.keyIdentifier.matches(keyIdentifier)) { if (!it.keyIdentifier.matches(keyIdentifier)) {
if (signatures.subkeyBindings[it.keyID] == null) { if (signatures.subkeyBindings[it.keyIdentifier.keyId] == null) {
LOGGER.debug("Subkey ${it.keyID.openPgpKeyId()} has no binding signature.") LOGGER.debug("Subkey ${it.keyIdentifier} has no binding signature.")
return@filter false return@filter false
} }
} }
if (!it.isEncryptionKey) { if (!it.pgpPublicKey.isEncryptionKey) {
LOGGER.debug("(Sub-?)Key ${it.keyID.openPgpKeyId()} is not encryption-capable.") LOGGER.debug("(Sub-?)Key ${it.keyIdentifier} is not encryption-capable.")
return@filter false return@filter false
} }
return@filter true return@filter true
@ -204,8 +209,7 @@ class KeyRingInfo(
} }
/** List of all subkeys that can be used to sign a message. */ /** List of all subkeys that can be used to sign a message. */
val signingSubkeys: List<PGPPublicKey> = val signingSubkeys: List<OpenPGPComponentKey> = keys.getSigningKeys(referenceDate)
keys.getSigningKeys(referenceDate).map { it.pgpPublicKey }
/** Whether the key is usable for encryption. */ /** Whether the key is usable for encryption. */
val isUsableForEncryption: Boolean = val isUsableForEncryption: Boolean =
@ -222,7 +226,7 @@ class KeyRingInfo(
/** Whether the key is actually usable to sign messages. */ /** Whether the key is actually usable to sign messages. */
val isUsableForSigning: Boolean = val isUsableForSigning: Boolean =
isSigningCapable && signingSubkeys.any { isSecretKeyAvailable(it.keyID) } isSigningCapable && signingSubkeys.any { isSecretKeyAvailable(it.keyIdentifier) }
/** [HashAlgorithm] preferences of the primary user-ID or if absent, of the primary key. */ /** [HashAlgorithm] preferences of the primary user-ID or if absent, of the primary key. */
val preferredHashAlgorithms: Set<HashAlgorithm> val preferredHashAlgorithms: Set<HashAlgorithm>
@ -254,6 +258,10 @@ class KeyRingInfo(
return getSubkeyExpirationDate(fingerprint.keyId) return getSubkeyExpirationDate(fingerprint.keyId)
} }
fun getSubkeyExpirationDate(keyIdentifier: KeyIdentifier): Date? {
return getSubkeyExpirationDate(keyIdentifier.keyId)
}
/** /**
* Return the expiration date of the subkey with the provided keyId. * Return the expiration date of the subkey with the provided keyId.
* *
@ -284,7 +292,7 @@ class KeyRingInfo(
} }
val primaryKeyExpiration = primaryKeyExpirationDate val primaryKeyExpiration = primaryKeyExpirationDate
val keysWithFlag: List<PGPPublicKey> = getKeysWithKeyFlag(use) val keysWithFlag: List<OpenPGPComponentKey> = getKeysWithKeyFlag(use)
if (keysWithFlag.isEmpty()) if (keysWithFlag.isEmpty())
throw NoSuchElementException("No key with the required key flag found.") throw NoSuchElementException("No key with the required key flag found.")
@ -292,7 +300,9 @@ class KeyRingInfo(
val latestSubkeyExpiration = val latestSubkeyExpiration =
keysWithFlag keysWithFlag
.map { key -> .map { key ->
getSubkeyExpirationDate(key.keyID).also { if (it == null) nonExpiring = true } getSubkeyExpirationDate(key.keyIdentifier).also {
if (it == null) nonExpiring = true
}
} }
.filterNotNull() .filterNotNull()
.maxByOrNull { it } .maxByOrNull { it }
@ -318,8 +328,8 @@ class KeyRingInfo(
* @param flag flag * @param flag flag
* @return keys with flag * @return keys with flag
*/ */
fun getKeysWithKeyFlag(flag: KeyFlag): List<PGPPublicKey> = fun getKeysWithKeyFlag(flag: KeyFlag): List<OpenPGPComponentKey> =
publicKeys.filter { getKeyFlagsOf(it.keyID).contains(flag) } publicKeys.filter { getKeyFlagsOf(it.keyIdentifier).contains(flag) }
/** /**
* Return a list of all subkeys which can be used to encrypt a message for the given user-ID. * Return a list of all subkeys which can be used to encrypt a message for the given user-ID.
@ -329,7 +339,7 @@ class KeyRingInfo(
fun getEncryptionSubkeys( fun getEncryptionSubkeys(
userId: CharSequence?, userId: CharSequence?,
purpose: EncryptionPurpose purpose: EncryptionPurpose
): List<PGPPublicKey> { ): List<OpenPGPComponentKey> {
if (userId != null && !isUserIdValid(userId)) { if (userId != null && !isUserIdValid(userId)) {
throw UnboundUserIdException( throw UnboundUserIdException(
OpenPgpFingerprint.of(publicKey.pgpPublicKey), OpenPgpFingerprint.of(publicKey.pgpPublicKey),
@ -345,7 +355,7 @@ class KeyRingInfo(
* *
* @return subkeys which can be used for encryption * @return subkeys which can be used for encryption
*/ */
fun getEncryptionSubkeys(purpose: EncryptionPurpose): List<PGPPublicKey> { fun getEncryptionSubkeys(purpose: EncryptionPurpose): List<OpenPGPComponentKey> {
primaryKeyExpirationDate?.let { primaryKeyExpirationDate?.let {
if (it < referenceDate) { if (it < referenceDate) {
LOGGER.debug( LOGGER.debug(
@ -354,29 +364,29 @@ class KeyRingInfo(
} }
} }
return keys.pgpKeyRing.publicKeys return keys.keys
.asSequence() .asSequence()
.filter { .filter {
if (!isKeyValidlyBound(it.keyID)) { if (!isKeyValidlyBound(it.keyIdentifier)) {
LOGGER.debug("(Sub?)-Key ${it.keyID.openPgpKeyId()} is not validly bound.") LOGGER.debug("(Sub?)-Key ${it.keyIdentifier} is not validly bound.")
return@filter false return@filter false
} }
getSubkeyExpirationDate(it.keyID)?.let { exp -> getSubkeyExpirationDate(it.keyIdentifier)?.let { exp ->
if (exp < referenceDate) { if (exp < referenceDate) {
LOGGER.debug( LOGGER.debug(
"(Sub?)-Key ${it.keyID.openPgpKeyId()} is expired on ${DateUtil.formatUTCDate(exp)}.") "(Sub?)-Key ${it.keyIdentifier} is expired on ${DateUtil.formatUTCDate(exp)}.")
return@filter false return@filter false
} }
} }
if (!it.isEncryptionKey) { if (!it.pgpPublicKey.isEncryptionKey) {
LOGGER.debug( LOGGER.debug(
"(Sub?)-Key ${it.keyID.openPgpKeyId()} algorithm is not capable of encryption.") "(Sub?)-Key ${it.keyIdentifier} algorithm is not capable of encryption.")
return@filter false return@filter false
} }
val keyFlags = getKeyFlagsOf(it.keyID) val keyFlags = getKeyFlagsOf(it.keyIdentifier)
when (purpose) { when (purpose) {
EncryptionPurpose.COMMUNICATIONS -> EncryptionPurpose.COMMUNICATIONS ->
return@filter keyFlags.contains(KeyFlag.ENCRYPT_COMMS) return@filter keyFlags.contains(KeyFlag.ENCRYPT_COMMS)
@ -519,7 +529,7 @@ class KeyRingInfo(
* @param keyId key id * @param keyId key id
* @return public key or null * @return public key or null
*/ */
fun getPublicKey(keyId: Long): PGPPublicKey? = keys.pgpKeyRing.getPublicKey(keyId) fun getPublicKey(keyId: Long): OpenPGPComponentKey? = keys.getKey(KeyIdentifier(keyId))
/** /**
* Return the secret key with the given key id. * Return the secret key with the given key id.
@ -527,10 +537,15 @@ class KeyRingInfo(
* @param keyId key id * @param keyId key id
* @return secret key or null * @return secret key or null
*/ */
fun getSecretKey(keyId: Long): PGPSecretKey? = fun getSecretKey(keyId: Long): OpenPGPSecretKey? = getSecretKey(KeyIdentifier(keyId))
when (keys.pgpKeyRing) {
is PGPSecretKeyRing -> (keys.pgpKeyRing as PGPSecretKeyRing).getSecretKey(keyId) fun getSecretKey(keyIdentifier: KeyIdentifier): OpenPGPSecretKey? =
else -> null if (keys.isSecretKey) {
(keys as OpenPGPKey).getSecretKey(keyIdentifier)
} else null
fun isSecretKeyAvailable(keyId: Long): Boolean {
return isSecretKeyAvailable(KeyIdentifier(keyId))
} }
/** /**
@ -539,10 +554,10 @@ class KeyRingInfo(
* *
* @return availability of the secret key * @return availability of the secret key
*/ */
fun isSecretKeyAvailable(keyId: Long): Boolean { fun isSecretKeyAvailable(keyIdentifier: KeyIdentifier): Boolean {
return getSecretKey(keyId)?.let { return getSecretKey(keyIdentifier)?.let {
return if (it.s2K == null) true // Unencrypted key return if (it.pgpSecretKey.s2K == null) true // Unencrypted key
else it.s2K.type !in 100..110 // Secret key on smart-card else it.pgpSecretKey.s2K.type !in 100..110 // Secret key on smart-card
} }
?: false // Missing secret key ?: false // Missing secret key
} }
@ -553,8 +568,8 @@ class KeyRingInfo(
* @param fingerprint fingerprint * @param fingerprint fingerprint
* @return public key or null * @return public key or null
*/ */
fun getPublicKey(fingerprint: OpenPgpFingerprint): PGPPublicKey? = fun getPublicKey(fingerprint: OpenPgpFingerprint): OpenPGPComponentKey? =
keys.pgpKeyRing.getPublicKey(fingerprint.bytes) keys.getKey(KeyIdentifier(fingerprint.bytes))
/** /**
* Return the secret key with the given fingerprint. * Return the secret key with the given fingerprint.
@ -562,15 +577,11 @@ class KeyRingInfo(
* @param fingerprint fingerprint * @param fingerprint fingerprint
* @return secret key or null * @return secret key or null
*/ */
fun getSecretKey(fingerprint: OpenPgpFingerprint): PGPSecretKey? = fun getSecretKey(fingerprint: OpenPgpFingerprint): OpenPGPSecretKey? =
when (keys.pgpKeyRing) { getSecretKey(KeyIdentifier(fingerprint.bytes))
is PGPSecretKeyRing ->
(keys.pgpKeyRing as PGPSecretKeyRing).getSecretKey(fingerprint.bytes)
else -> null
}
fun getPublicKey(keyIdentifier: KeyIdentifier): PGPPublicKey? { fun getPublicKey(keyIdentifier: KeyIdentifier): OpenPGPComponentKey? {
return keys.pgpKeyRing.getPublicKey(keyIdentifier) return keys.getKey(keyIdentifier)
} }
/** /**
@ -580,11 +591,11 @@ class KeyRingInfo(
* @throws IllegalArgumentException if the identifier's primary key does not match the primary * @throws IllegalArgumentException if the identifier's primary key does not match the primary
* key of the key. * key of the key.
*/ */
fun getPublicKey(identifier: SubkeyIdentifier): PGPPublicKey? { fun getPublicKey(identifier: SubkeyIdentifier): OpenPGPComponentKey? {
require(publicKey.keyIdentifier.equals(identifier.keyIdentifier)) { require(publicKey.keyIdentifier.equals(identifier.keyIdentifier)) {
"Mismatching primary key ID." "Mismatching primary key ID."
} }
return keys.pgpKeyRing.getPublicKey(identifier.subkeyIdentifier) return getPublicKey(identifier.subkeyIdentifier)
} }
/** /**
@ -594,16 +605,8 @@ class KeyRingInfo(
* @throws IllegalArgumentException if the identifier's primary key does not match the primary * @throws IllegalArgumentException if the identifier's primary key does not match the primary
* key of the key. * key of the key.
*/ */
fun getSecretKey(identifier: SubkeyIdentifier): PGPSecretKey? = fun getSecretKey(identifier: SubkeyIdentifier): OpenPGPComponentKey? =
when (keys.pgpKeyRing) { getSecretKey(identifier.subkeyIdentifier)
is PGPSecretKeyRing -> {
require(publicKey.keyIdentifier.equals(identifier.keyIdentifier)) {
"Mismatching primary key ID."
}
(keys.pgpKeyRing as PGPSecretKeyRing).getSecretKey(identifier.subkeyIdentifier)
}
else -> null
}
fun isKeyValidlyBound(keyIdentifier: KeyIdentifier): Boolean { fun isKeyValidlyBound(keyIdentifier: KeyIdentifier): Boolean {
return isKeyValidlyBound(keyIdentifier.keyId) return isKeyValidlyBound(keyIdentifier.keyId)

View file

@ -120,11 +120,11 @@ public class InvestigateMultiSEIPMessageHandlingTest {
public void generateTestMessage() throws PGPException, IOException { public void generateTestMessage() throws PGPException, IOException {
PGPSecretKeyRing ring1 = PGPainless.readKeyRing().secretKeyRing(KEY1); PGPSecretKeyRing ring1 = PGPainless.readKeyRing().secretKeyRing(KEY1);
KeyRingInfo info1 = PGPainless.inspectKeyRing(ring1); KeyRingInfo info1 = PGPainless.inspectKeyRing(ring1);
PGPPublicKey cryptKey1 = info1.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); PGPPublicKey cryptKey1 = info1.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getPGPPublicKey();
PGPSecretKey signKey1 = ring1.getSecretKey(info1.getSigningSubkeys().get(0).getKeyID()); PGPSecretKey signKey1 = ring1.getSecretKey(info1.getSigningSubkeys().get(0).getKeyIdentifier());
PGPSecretKeyRing ring2 = PGPainless.readKeyRing().secretKeyRing(KEY2); PGPSecretKeyRing ring2 = PGPainless.readKeyRing().secretKeyRing(KEY2);
KeyRingInfo info2 = PGPainless.inspectKeyRing(ring2); KeyRingInfo info2 = PGPainless.inspectKeyRing(ring2);
PGPSecretKey signKey2 = ring2.getSecretKey(info2.getSigningSubkeys().get(0).getKeyID()); PGPSecretKey signKey2 = ring2.getSecretKey(info2.getSigningSubkeys().get(0).getKeyIdentifier());
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ArmoredOutputStream armorOut = new ArmoredOutputStream(out); ArmoredOutputStream armorOut = new ArmoredOutputStream(out);

View file

@ -68,9 +68,9 @@ public class CachingBcPublicKeyDataDecryptorFactoryTest {
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
SubkeyIdentifier decryptionKey = new SubkeyIdentifier(secretKeys, SubkeyIdentifier decryptionKey = new SubkeyIdentifier(secretKeys,
info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyID()); info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyIdentifier());
PGPSecretKey secretKey = secretKeys.getSecretKey(decryptionKey.getSubkeyId()); PGPSecretKey secretKey = secretKeys.getSecretKey(decryptionKey.getKeyIdentifier());
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
CachingBcPublicKeyDataDecryptorFactory cachingFactory = new CachingBcPublicKeyDataDecryptorFactory( CachingBcPublicKeyDataDecryptorFactory cachingFactory = new CachingBcPublicKeyDataDecryptorFactory(
privateKey, decryptionKey); privateKey, decryptionKey);

View file

@ -14,9 +14,8 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
@ -66,14 +65,14 @@ public class CertificateWithMissingSecretKeyTest {
private static final long signingSubkeyId = -7647663290973502178L; private static final long signingSubkeyId = -7647663290973502178L;
private static PGPSecretKeyRing missingSigningSecKey; private static PGPSecretKeyRing missingSigningSecKey;
private static long encryptionSubkeyId; private static KeyIdentifier encryptionSubkeyId;
private static PGPSecretKeyRing missingDecryptionSecKey; private static PGPSecretKeyRing missingDecryptionSecKey;
private static final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); private static final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
@BeforeAll @BeforeAll
public static void prepare() throws IOException, PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { public static void prepare() throws IOException {
// missing signing sec key we read from bytes // missing signing sec key we read from bytes
missingSigningSecKey = PGPainless.readKeyRing().secretKeyRing(MISSING_SIGNING_SECKEY); missingSigningSecKey = PGPainless.readKeyRing().secretKeyRing(MISSING_SIGNING_SECKEY);
@ -81,9 +80,9 @@ public class CertificateWithMissingSecretKeyTest {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Missing Decryption Key <missing@decryption.key>"); .modernKeyRing("Missing Decryption Key <missing@decryption.key>");
encryptionSubkeyId = PGPainless.inspectKeyRing(secretKeys) encryptionSubkeyId = PGPainless.inspectKeyRing(secretKeys)
.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyID(); .getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyIdentifier();
// remove the encryption/decryption secret key // remove the encryption/decryption secret key
missingDecryptionSecKey = KeyRingUtils.stripSecretKey(secretKeys, encryptionSubkeyId); missingDecryptionSecKey = KeyRingUtils.stripSecretKey(secretKeys, encryptionSubkeyId.getKeyId());
} }
@Test @Test

View file

@ -6,10 +6,10 @@ package org.pgpainless.decryption_verification;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
@ -41,7 +41,8 @@ public class CustomPublicKeyDataDecryptorFactoryTest {
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing().modernKeyRing("Alice"); PGPSecretKeyRing secretKey = PGPainless.generateKeyRing().modernKeyRing("Alice");
PGPPublicKeyRing cert = PGPainless.extractCertificate(secretKey); PGPPublicKeyRing cert = PGPainless.extractCertificate(secretKey);
KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); KeyRingInfo info = PGPainless.inspectKeyRing(secretKey);
PGPPublicKey encryptionKey = info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); OpenPGPCertificate.OpenPGPComponentKey encryptionKey =
info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
// Encrypt a test message // Encrypt a test message
String plaintext = "Hello, World!\n"; String plaintext = "Hello, World!\n";
@ -59,7 +60,7 @@ public class CustomPublicKeyDataDecryptorFactoryTest {
throws HardwareSecurity.HardwareSecurityException { throws HardwareSecurity.HardwareSecurityException {
// Emulate hardware decryption. // Emulate hardware decryption.
try { try {
PGPSecretKey decryptionKey = secretKey.getSecretKey(encryptionKey.getKeyID()); PGPSecretKey decryptionKey = secretKey.getSecretKey(encryptionKey.getKeyIdentifier());
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKey, Passphrase.emptyPassphrase()); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKey, Passphrase.emptyPassphrase());
PublicKeyDataDecryptorFactory internal = new BcPublicKeyDataDecryptorFactory(privateKey); PublicKeyDataDecryptorFactory internal = new BcPublicKeyDataDecryptorFactory(privateKey);
return internal.recoverSessionData(keyAlgorithm, new byte[][] {sessionKeyData}); return internal.recoverSessionData(keyAlgorithm, new byte[][] {sessionKeyData});
@ -75,7 +76,7 @@ public class CustomPublicKeyDataDecryptorFactoryTest {
.withOptions(ConsumerOptions.get() .withOptions(ConsumerOptions.get()
.addCustomDecryptorFactory( .addCustomDecryptorFactory(
new HardwareSecurity.HardwareDataDecryptorFactory( new HardwareSecurity.HardwareDataDecryptorFactory(
new SubkeyIdentifier(cert, encryptionKey.getKeyID()), new SubkeyIdentifier(cert, encryptionKey.getKeyIdentifier()),
hardwareDecryptionCallback))); hardwareDecryptionCallback)));
ByteArrayOutputStream decryptedOut = new ByteArrayOutputStream(); ByteArrayOutputStream decryptedOut = new ByteArrayOutputStream();

View file

@ -13,8 +13,8 @@ import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@ -144,10 +144,11 @@ public class DecryptHiddenRecipientMessageTest {
assertEquals(0L, metadata.getRecipientKeyIds().get(0)); assertEquals(0L, metadata.getRecipientKeyIds().get(0));
KeyRingInfo info = new KeyRingInfo(secretKeys); KeyRingInfo info = new KeyRingInfo(secretKeys);
List<PGPPublicKey> encryptionKeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY); List<OpenPGPCertificate.OpenPGPComponentKey> encryptionKeys =
info.getEncryptionSubkeys(EncryptionPurpose.ANY);
assertEquals(1, encryptionKeys.size()); assertEquals(1, encryptionKeys.size());
assertEquals(new SubkeyIdentifier(secretKeys, encryptionKeys.get(0).getKeyID()), metadata.getDecryptionKey()); assertEquals(new SubkeyIdentifier(secretKeys, encryptionKeys.get(0).getKeyIdentifier()), metadata.getDecryptionKey());
assertEquals("Hello Recipient :)", out.toString()); assertEquals("Hello Recipient :)", out.toString());
} }
} }

View file

@ -14,14 +14,12 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -44,7 +42,7 @@ public class MissingPassphraseForDecryptionTest {
private byte[] message; private byte[] message;
@BeforeEach @BeforeEach
public void setup() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { public void setup() throws PGPException, IOException {
secretKeys = PGPainless.generateKeyRing().modernKeyRing("Test", passphrase); secretKeys = PGPainless.generateKeyRing().modernKeyRing("Test", passphrase);
PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKeys); PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKeys);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -91,7 +89,8 @@ public class MissingPassphraseForDecryptionTest {
@Test @Test
public void throwExceptionStrategy() throws PGPException, IOException { public void throwExceptionStrategy() throws PGPException, IOException {
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
List<PGPPublicKey> encryptionKeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY); List<OpenPGPCertificate.OpenPGPComponentKey> encryptionKeys =
info.getEncryptionSubkeys(EncryptionPurpose.ANY);
SecretKeyPassphraseProvider callback = new SecretKeyPassphraseProvider() { SecretKeyPassphraseProvider callback = new SecretKeyPassphraseProvider() {
@Override @Override
@ -118,8 +117,8 @@ public class MissingPassphraseForDecryptionTest {
} catch (MissingPassphraseException e) { } catch (MissingPassphraseException e) {
assertFalse(e.getKeyIds().isEmpty()); assertFalse(e.getKeyIds().isEmpty());
assertEquals(encryptionKeys.size(), e.getKeyIds().size()); assertEquals(encryptionKeys.size(), e.getKeyIds().size());
for (PGPPublicKey encryptionKey : encryptionKeys) { for (OpenPGPCertificate.OpenPGPComponentKey encryptionKey : encryptionKeys) {
assertTrue(e.getKeyIds().contains(new SubkeyIdentifier(secretKeys, encryptionKey.getKeyID()))); assertTrue(e.getKeyIds().contains(new SubkeyIdentifier(secretKeys, encryptionKey.getKeyIdentifier())));
} }
} }
} }

View file

@ -12,13 +12,11 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -39,9 +37,10 @@ import org.pgpainless.key.util.KeyRingUtils;
public class VerifyWithMissingPublicKeyCallbackTest { public class VerifyWithMissingPublicKeyCallbackTest {
@Test @Test
public void testMissingPublicKeyCallback() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { public void testMissingPublicKeyCallback() throws PGPException, IOException {
PGPSecretKeyRing signingSecKeys = PGPainless.generateKeyRing().modernKeyRing("alice"); PGPSecretKeyRing signingSecKeys = PGPainless.generateKeyRing().modernKeyRing("alice");
PGPPublicKey signingKey = new KeyRingInfo(signingSecKeys).getSigningSubkeys().get(0); OpenPGPCertificate.OpenPGPComponentKey signingKey =
new KeyRingInfo(signingSecKeys).getSigningSubkeys().get(0);
PGPPublicKeyRing signingPubKeys = KeyRingUtils.publicKeyRingFrom(signingSecKeys); PGPPublicKeyRing signingPubKeys = KeyRingUtils.publicKeyRingFrom(signingSecKeys);
PGPPublicKeyRing unrelatedKeys = TestKeys.getJulietPublicKeyRing(); PGPPublicKeyRing unrelatedKeys = TestKeys.getJulietPublicKeyRing();
@ -63,7 +62,7 @@ public class VerifyWithMissingPublicKeyCallbackTest {
.setMissingCertificateCallback(new MissingPublicKeyCallback() { .setMissingCertificateCallback(new MissingPublicKeyCallback() {
@Override @Override
public PGPPublicKeyRing onMissingPublicKeyEncountered(long keyId) { public PGPPublicKeyRing onMissingPublicKeyEncountered(long keyId) {
assertEquals(signingKey.getKeyID(), keyId, "Signing key-ID mismatch."); assertEquals(signingKey.getKeyIdentifier().getKeyId(), keyId, "Signing key-ID mismatch.");
return signingPubKeys; return signingPubKeys;
} }
})); }));

View file

@ -5,10 +5,10 @@
package org.pgpainless.encryption_signing; package org.pgpainless.encryption_signing;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -31,8 +31,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -50,7 +48,7 @@ public class MultiSigningSubkeyTest {
private static SecretKeyRingProtector protector; private static SecretKeyRingProtector protector;
@BeforeAll @BeforeAll
public static void generateKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { public static void generateKey() {
signingKey = PGPainless.buildKeyRing() signingKey = PGPainless.buildKeyRing()
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
.addSubkey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.SIGN_DATA)) .addSubkey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.SIGN_DATA))
@ -59,10 +57,10 @@ public class MultiSigningSubkeyTest {
.addUserId("Alice <alice@pgpainless.org>") .addUserId("Alice <alice@pgpainless.org>")
.build(); .build();
signingCert = PGPainless.extractCertificate(signingKey); signingCert = PGPainless.extractCertificate(signingKey);
Iterator<PGPPublicKey> signingSubkeys = PGPainless.inspectKeyRing(signingKey).getSigningSubkeys().listIterator(); Iterator<OpenPGPCertificate.OpenPGPComponentKey> signingSubkeys = PGPainless.inspectKeyRing(signingKey).getSigningSubkeys().listIterator();
primaryKey = new SubkeyIdentifier(signingKey, signingSubkeys.next().getKeyID()); primaryKey = new SubkeyIdentifier(signingKey, signingSubkeys.next().getKeyIdentifier());
signingKey1 = new SubkeyIdentifier(signingKey, signingSubkeys.next().getKeyID()); signingKey1 = new SubkeyIdentifier(signingKey, signingSubkeys.next().getKeyIdentifier());
signingKey2 = new SubkeyIdentifier(signingKey, signingSubkeys.next().getKeyID()); signingKey2 = new SubkeyIdentifier(signingKey, signingSubkeys.next().getKeyIdentifier());
protector = SecretKeyRingProtector.unprotectedKeys(); protector = SecretKeyRingProtector.unprotectedKeys();
} }

View file

@ -14,8 +14,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
@ -60,7 +58,7 @@ public class SigningTest {
PGPSecretKeyRing cryptieKeys = TestKeys.getCryptieSecretKeyRing(); PGPSecretKeyRing cryptieKeys = TestKeys.getCryptieSecretKeyRing();
KeyRingInfo cryptieInfo = new KeyRingInfo(cryptieKeys); KeyRingInfo cryptieInfo = new KeyRingInfo(cryptieKeys);
PGPSecretKey cryptieSigningKey = cryptieKeys.getSecretKey(cryptieInfo.getSigningSubkeys().get(0).getKeyID()); PGPSecretKey cryptieSigningKey = cryptieKeys.getSecretKey(cryptieInfo.getSigningSubkeys().get(0).getKeyIdentifier());
PGPPublicKeyRingCollection keys = new PGPPublicKeyRingCollection(Arrays.asList(julietKeys, romeoKeys)); PGPPublicKeyRingCollection keys = new PGPPublicKeyRingCollection(Arrays.asList(julietKeys, romeoKeys));
@ -115,8 +113,7 @@ public class SigningTest {
@TestTemplate @TestTemplate
@ExtendWith(TestAllImplementations.class) @ExtendWith(TestAllImplementations.class)
public void testSignWithInvalidUserIdFails() public void testSignWithInvalidUserIdFails() {
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("alice", "password123"); .modernKeyRing("alice", "password123");
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("password123")); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("password123"));
@ -131,7 +128,7 @@ public class SigningTest {
@TestTemplate @TestTemplate
@ExtendWith(TestAllImplementations.class) @ExtendWith(TestAllImplementations.class)
public void testSignWithRevokedUserIdFails() public void testSignWithRevokedUserIdFails()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { throws PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("alice", "password123"); .modernKeyRing("alice", "password123");
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith( SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(
@ -184,7 +181,7 @@ public class SigningTest {
@TestTemplate @TestTemplate
@ExtendWith(TestAllImplementations.class) @ExtendWith(TestAllImplementations.class)
public void negotiateHashAlgorithmChoseFallbackIfEmptyPreferences() public void negotiateHashAlgorithmChoseFallbackIfEmptyPreferences()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { throws PGPException, IOException {
PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing()
.setPrimaryKey(KeySpec.getBuilder( .setPrimaryKey(KeySpec.getBuilder(
KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA) KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
@ -214,7 +211,7 @@ public class SigningTest {
@TestTemplate @TestTemplate
@ExtendWith(TestAllImplementations.class) @ExtendWith(TestAllImplementations.class)
public void negotiateHashAlgorithmChoseFallbackIfUnacceptablePreferences() public void negotiateHashAlgorithmChoseFallbackIfUnacceptablePreferences()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { throws PGPException, IOException {
PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing()
.setPrimaryKey( .setPrimaryKey(
KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA) KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
@ -243,8 +240,7 @@ public class SigningTest {
@TestTemplate @TestTemplate
@ExtendWith(TestAllImplementations.class) @ExtendWith(TestAllImplementations.class)
public void signingWithNonCapableKeyThrowsKeyCannotSignException() public void signingWithNonCapableKeyThrowsKeyCannotSignException() {
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing()
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER)) .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER))
.addUserId("Alice") .addUserId("Alice")
@ -259,8 +255,7 @@ public class SigningTest {
@TestTemplate @TestTemplate
@ExtendWith(TestAllImplementations.class) @ExtendWith(TestAllImplementations.class)
public void signWithInvalidUserIdThrowsKeyValidationError() public void signWithInvalidUserIdThrowsKeyValidationError() {
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing()
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519),
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))

View file

@ -72,9 +72,9 @@ public class GenerateKeys {
assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(), assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(),
keyInfo.getAlgorithm().getAlgorithmId()); keyInfo.getAlgorithm().getAlgorithmId());
assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(), assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(),
keyInfo.getSigningSubkeys().get(0).getAlgorithm()); keyInfo.getSigningSubkeys().get(0).getPGPPublicKey().getAlgorithm());
assertEquals(PublicKeyAlgorithm.ECDH.getAlgorithmId(), assertEquals(PublicKeyAlgorithm.ECDH.getAlgorithmId(),
keyInfo.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getAlgorithm()); keyInfo.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getPGPPublicKey().getAlgorithm());
} }
/** /**

View file

@ -15,10 +15,11 @@ import java.security.NoSuchAlgorithmException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -44,19 +45,18 @@ public class ModifyKeys {
private final String originalPassphrase = "p4ssw0rd"; private final String originalPassphrase = "p4ssw0rd";
private PGPSecretKeyRing secretKey; private PGPSecretKeyRing secretKey;
private long primaryKeyId; private long primaryKeyId;
private long encryptionSubkeyId; private KeyIdentifier encryptionSubkeyId;
private long signingSubkeyId; private KeyIdentifier signingSubkeyId;
@BeforeEach @BeforeEach
public void generateKey() public void generateKey() {
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
secretKey = PGPainless.generateKeyRing() secretKey = PGPainless.generateKeyRing()
.modernKeyRing(userId, originalPassphrase); .modernKeyRing(userId, originalPassphrase);
KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); KeyRingInfo info = PGPainless.inspectKeyRing(secretKey);
primaryKeyId = info.getKeyIdentifier().getKeyId(); primaryKeyId = info.getKeyIdentifier().getKeyId();
encryptionSubkeyId = info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyID(); encryptionSubkeyId = info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyIdentifier();
signingSubkeyId = info.getSigningSubkeys().get(0).getKeyID(); signingSubkeyId = info.getSigningSubkeys().get(0).getKeyIdentifier();
} }
/** /**
@ -75,7 +75,7 @@ public class ModifyKeys {
* This example demonstrates how to export a secret key or certificate to an ASCII armored string. * This example demonstrates how to export a secret key or certificate to an ASCII armored string.
*/ */
@Test @Test
public void toAsciiArmoredString() throws IOException { public void toAsciiArmoredString() {
PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKey); PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKey);
String asciiArmoredSecretKey = PGPainless.asciiArmor(secretKey); String asciiArmoredSecretKey = PGPainless.asciiArmor(secretKey);
@ -111,7 +111,7 @@ public class ModifyKeys {
public void changeSingleSubkeyPassphrase() throws PGPException { public void changeSingleSubkeyPassphrase() throws PGPException {
secretKey = PGPainless.modifyKeyRing(secretKey) secretKey = PGPainless.modifyKeyRing(secretKey)
// Here we change the passphrase of the encryption subkey // Here we change the passphrase of the encryption subkey
.changeSubKeyPassphraseFromOldPassphrase(encryptionSubkeyId, Passphrase.fromPassword(originalPassphrase)) .changeSubKeyPassphraseFromOldPassphrase(encryptionSubkeyId.getKeyId(), Passphrase.fromPassword(originalPassphrase))
.withSecureDefaultSettings() .withSecureDefaultSettings()
.toNewPassphrase(Passphrase.fromPassword("cryptP4ssphr4s3")) .toNewPassphrase(Passphrase.fromPassword("cryptP4ssphr4s3"))
.done(); .done();
@ -147,13 +147,13 @@ public class ModifyKeys {
* This example demonstrates how to add an additional subkey to an existing key. * This example demonstrates how to add an additional subkey to an existing key.
* Prerequisites are a {@link SecretKeyRingProtector} that is capable of unlocking the primary key of the existing key, * Prerequisites are a {@link SecretKeyRingProtector} that is capable of unlocking the primary key of the existing key,
* and a {@link Passphrase} for the new subkey. * and a {@link Passphrase} for the new subkey.
* * <p>
* There are two ways to add a subkey into an existing key; * There are two ways to add a subkey into an existing key;
* Either the subkey gets generated on the fly (see below), * Either the subkey gets generated on the fly (see below),
* or the subkey already exists. In the latter case, the user has to provide * or the subkey already exists. In the latter case, the user has to provide
* {@link org.bouncycastle.openpgp.PGPSignatureSubpacketVector PGPSignatureSubpacketVectors} for the binding signature * {@link org.bouncycastle.openpgp.PGPSignatureSubpacketVector PGPSignatureSubpacketVectors} for the binding signature
* manually. * manually.
* * <p>
* Once the subkey is added, it can be decrypted using the provided subkey passphrase. * Once the subkey is added, it can be decrypted using the provided subkey passphrase.
*/ */
@Test @Test
@ -173,9 +173,9 @@ public class ModifyKeys {
KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); KeyRingInfo info = PGPainless.inspectKeyRing(secretKey);
assertEquals(4, info.getSecretKeys().size()); assertEquals(4, info.getSecretKeys().size());
assertEquals(4, info.getPublicKeys().size()); assertEquals(4, info.getPublicKeys().size());
List<PGPPublicKey> encryptionSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.COMMUNICATIONS); List<OpenPGPCertificate.OpenPGPComponentKey> encryptionSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.COMMUNICATIONS);
assertEquals(2, encryptionSubkeys.size()); assertEquals(2, encryptionSubkeys.size());
UnlockSecretKey.unlockSecretKey(secretKey.getSecretKey(encryptionSubkeys.get(1).getKeyID()), subkeyPassphrase); UnlockSecretKey.unlockSecretKey(secretKey.getSecretKey(encryptionSubkeys.get(1).getKeyIdentifier()), subkeyPassphrase);
} }
/** /**

View file

@ -12,13 +12,11 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -38,7 +36,7 @@ public class Sign {
private static SecretKeyRingProtector protector; private static SecretKeyRingProtector protector;
@BeforeAll @BeforeAll
public static void prepare() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { public static void prepare() {
secretKey = PGPainless.generateKeyRing().modernKeyRing("Emilia Example <emilia@example.org>"); secretKey = PGPainless.generateKeyRing().modernKeyRing("Emilia Example <emilia@example.org>");
protector = SecretKeyRingProtector.unprotectedKeys(); // no password protector = SecretKeyRingProtector.unprotectedKeys(); // no password
} }
@ -94,8 +92,8 @@ public class Sign {
EncryptionResult result = signingStream.getResult(); EncryptionResult result = signingStream.getResult();
PGPPublicKey signingKey = PGPainless.inspectKeyRing(secretKey).getSigningSubkeys().get(0); OpenPGPCertificate.OpenPGPComponentKey signingKey = PGPainless.inspectKeyRing(secretKey).getSigningSubkeys().get(0);
PGPSignature signature = result.getDetachedSignatures().get(new SubkeyIdentifier(secretKey, signingKey.getKeyID())).iterator().next(); PGPSignature signature = result.getDetachedSignatures().get(new SubkeyIdentifier(secretKey, signingKey.getKeyIdentifier())).iterator().next();
String detachedSignature = ArmorUtils.toAsciiArmoredString(signature.getEncoded()); String detachedSignature = ArmorUtils.toAsciiArmoredString(signature.getEncoded());
assertTrue(detachedSignature.startsWith("-----BEGIN PGP SIGNATURE-----")); assertTrue(detachedSignature.startsWith("-----BEGIN PGP SIGNATURE-----"));

View file

@ -18,10 +18,10 @@ import java.util.List;
import org.bouncycastle.bcpg.sig.IssuerFingerprint; import org.bouncycastle.bcpg.sig.IssuerFingerprint;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
@ -107,7 +107,7 @@ public class KeyGenerationSubpacketsTest {
throws PGPException { throws PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice"); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice");
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
List<PGPPublicKey> keysBefore = info.getPublicKeys(); List<OpenPGPCertificate.OpenPGPComponentKey> keysBefore = info.getPublicKeys();
secretKeys = PGPainless.modifyKeyRing(secretKeys) secretKeys = PGPainless.modifyKeyRing(secretKeys)
.addSubKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.SIGN_DATA).build(), .addSubKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.SIGN_DATA).build(),
@ -116,12 +116,12 @@ public class KeyGenerationSubpacketsTest {
info = PGPainless.inspectKeyRing(secretKeys); info = PGPainless.inspectKeyRing(secretKeys);
List<PGPPublicKey> keysAfter = new ArrayList<>(info.getPublicKeys()); List<OpenPGPCertificate.OpenPGPComponentKey> keysAfter = new ArrayList<>(info.getPublicKeys());
keysAfter.removeAll(keysBefore); keysAfter.removeAll(keysBefore);
assertEquals(1, keysAfter.size()); assertEquals(1, keysAfter.size());
PGPPublicKey newSigningKey = keysAfter.get(0); OpenPGPCertificate.OpenPGPComponentKey newSigningKey = keysAfter.get(0);
PGPSignature bindingSig = info.getCurrentSubkeyBindingSignature(newSigningKey.getKeyID()); PGPSignature bindingSig = info.getCurrentSubkeyBindingSignature(newSigningKey.getKeyIdentifier().getKeyId());
assertNotNull(bindingSig); assertNotNull(bindingSig);
assureSignatureHasDefaultSubpackets(bindingSig, secretKeys, KeyFlag.SIGN_DATA); assureSignatureHasDefaultSubpackets(bindingSig, secretKeys, KeyFlag.SIGN_DATA);
assertNotNull(bindingSig.getHashedSubPackets().getEmbeddedSignatures().get(0)); assertNotNull(bindingSig.getHashedSubPackets().getEmbeddedSignatures().get(0));
@ -142,8 +142,8 @@ public class KeyGenerationSubpacketsTest {
keysAfter.removeAll(keysBefore); keysAfter.removeAll(keysBefore);
keysAfter.remove(newSigningKey); keysAfter.remove(newSigningKey);
assertEquals(1, keysAfter.size()); assertEquals(1, keysAfter.size());
PGPPublicKey newEncryptionKey = keysAfter.get(0); OpenPGPCertificate.OpenPGPComponentKey newEncryptionKey = keysAfter.get(0);
bindingSig = info.getCurrentSubkeyBindingSignature(newEncryptionKey.getKeyID()); bindingSig = info.getCurrentSubkeyBindingSignature(newEncryptionKey.getKeyIdentifier().getKeyId());
assertNotNull(bindingSig); assertNotNull(bindingSig);
assertNull(bindingSig.getHashedSubPackets().getIssuerFingerprint()); assertNull(bindingSig.getHashedSubPackets().getIssuerFingerprint());
assertEquals(KeyFlag.toBitmask(KeyFlag.ENCRYPT_COMMS), bindingSig.getHashedSubPackets().getKeyFlags()); assertEquals(KeyFlag.toBitmask(KeyFlag.ENCRYPT_COMMS), bindingSig.getHashedSubPackets().getKeyFlags());

View file

@ -25,10 +25,11 @@ import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.junit.JUtils; import org.junit.JUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.TestTemplate;
@ -162,7 +163,7 @@ public class KeyRingInfoTest {
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys); PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys), info.getSecretKey()); assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys), info.getSecretKey().getPGPSecretKey());
info = PGPainless.inspectKeyRing(publicKeys); info = PGPainless.inspectKeyRing(publicKeys);
assertNull(info.getSecretKey()); assertNull(info.getSecretKey());
@ -173,7 +174,7 @@ public class KeyRingInfoTest {
PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing(); PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing();
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
assertEquals(KeyRingUtils.requirePrimaryPublicKeyFrom(secretKeys), info.getPublicKey()); assertEquals(KeyRingUtils.requirePrimaryPublicKeyFrom(secretKeys), info.getPublicKey().getPGPPublicKey());
assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys), assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys),
KeyRingUtils.requireSecretKeyFrom(secretKeys, secretKeys.getPublicKey().getKeyID())); KeyRingUtils.requireSecretKeyFrom(secretKeys, secretKeys.getPublicKey().getKeyID()));
@ -229,7 +230,7 @@ public class KeyRingInfoTest {
KeyFlag.ENCRYPT_STORAGE)) KeyFlag.ENCRYPT_STORAGE))
.addSubkey(KeySpec.getBuilder( .addSubkey(KeySpec.getBuilder(
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1), KeyFlag.SIGN_DATA)) KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1), KeyFlag.SIGN_DATA))
.addUserId(UserId.newBuilder().withName("Alice").withEmail("alice@pgpainless.org").build()) .addUserId(UserId.builder().withName("Alice").withEmail("alice@pgpainless.org").build())
.build(); .build();
Iterator<PGPSecretKey> keys = secretKeys.iterator(); Iterator<PGPSecretKey> keys = secretKeys.iterator();
@ -256,17 +257,17 @@ public class KeyRingInfoTest {
KeyRingInfo info = new KeyRingInfo(secretKeys); KeyRingInfo info = new KeyRingInfo(secretKeys);
List<PGPPublicKey> encryptionKeys = info.getKeysWithKeyFlag(KeyFlag.ENCRYPT_STORAGE); List<OpenPGPCertificate.OpenPGPComponentKey> encryptionKeys = info.getKeysWithKeyFlag(KeyFlag.ENCRYPT_STORAGE);
assertEquals(1, encryptionKeys.size()); assertEquals(1, encryptionKeys.size());
assertEquals(encryptionKey.getKeyID(), encryptionKeys.get(0).getKeyID()); assertEquals(encryptionKey.getKeyIdentifier(), encryptionKeys.get(0).getKeyIdentifier());
List<PGPPublicKey> signingKeys = info.getKeysWithKeyFlag(KeyFlag.SIGN_DATA); List<OpenPGPCertificate.OpenPGPComponentKey> signingKeys = info.getKeysWithKeyFlag(KeyFlag.SIGN_DATA);
assertEquals(1, signingKeys.size()); assertEquals(1, signingKeys.size());
assertEquals(signingKey.getKeyID(), signingKeys.get(0).getKeyID()); assertEquals(signingKey.getKeyIdentifier(), signingKeys.get(0).getKeyIdentifier());
List<PGPPublicKey> certKeys = info.getKeysWithKeyFlag(KeyFlag.CERTIFY_OTHER); List<OpenPGPCertificate.OpenPGPComponentKey> certKeys = info.getKeysWithKeyFlag(KeyFlag.CERTIFY_OTHER);
assertEquals(1, certKeys.size()); assertEquals(1, certKeys.size());
assertEquals(primaryKey.getKeyID(), certKeys.get(0).getKeyID()); assertEquals(primaryKey.getKeyIdentifier(), certKeys.get(0).getKeyIdentifier());
assertNotNull(info.getPrimaryKeyExpirationDate()); assertNotNull(info.getPrimaryKeyExpirationDate());
assertEquals(primaryKeyExpiration.getTime(), info.getPrimaryKeyExpirationDate().getTime(), 5); assertEquals(primaryKeyExpiration.getTime(), info.getPrimaryKeyExpirationDate().getTime(), 5);
@ -522,14 +523,15 @@ public class KeyRingInfoTest {
} }
@Test @Test
public void getSecretKeyTest() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { public void getSecretKeyTest() {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice"); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice");
OpenPGPKey key = new OpenPGPKey(secretKeys);
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
OpenPgpV4Fingerprint primaryKeyFingerprint = new OpenPgpV4Fingerprint(secretKeys); OpenPgpV4Fingerprint primaryKeyFingerprint = new OpenPgpV4Fingerprint(secretKeys);
PGPSecretKey primaryKey = info.getSecretKey(primaryKeyFingerprint); OpenPGPKey.OpenPGPSecretKey primaryKey = info.getSecretKey(primaryKeyFingerprint);
assertEquals(secretKeys.getSecretKey(), primaryKey); assertEquals(key.getPrimarySecretKey().getKeyIdentifier(), primaryKey.getKeyIdentifier());
} }
@Test @Test
@ -693,12 +695,16 @@ public class KeyRingInfoTest {
assertFalse(info.isKeyValidlyBound(unboundKey.getKeyId())); assertFalse(info.isKeyValidlyBound(unboundKey.getKeyId()));
List<PGPPublicKey> encryptionSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY); List<OpenPGPCertificate.OpenPGPComponentKey> encryptionSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY);
assertTrue(encryptionSubkeys.stream().map(OpenPgpV4Fingerprint::new).noneMatch(f -> f.equals(unboundKey)), assertTrue(encryptionSubkeys.stream()
.map(it -> new OpenPgpV4Fingerprint(it.getPGPPublicKey()))
.noneMatch(f -> f.equals(unboundKey)),
"Unbound subkey MUST NOT be considered a valid encryption subkey"); "Unbound subkey MUST NOT be considered a valid encryption subkey");
List<PGPPublicKey> signingSubkeys = info.getSigningSubkeys(); List<OpenPGPCertificate.OpenPGPComponentKey> signingSubkeys = info.getSigningSubkeys();
assertTrue(signingSubkeys.stream().map(OpenPgpV4Fingerprint::new).noneMatch(f -> f.equals(unboundKey)), assertTrue(signingSubkeys.stream()
.map(it -> new OpenPgpV4Fingerprint(it.getPGPPublicKey()))
.noneMatch(f -> f.equals(unboundKey)),
"Unbound subkey MUST NOT be considered a valid signing subkey"); "Unbound subkey MUST NOT be considered a valid signing subkey");
assertTrue(info.getKeyFlagsOf(unboundKey.getKeyId()).isEmpty()); assertTrue(info.getKeyFlagsOf(unboundKey.getKeyId()).isEmpty());

View file

@ -14,9 +14,9 @@ import java.util.List;
import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.bcpg.sig.NotationData;
import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.junit.JUtils; import org.junit.JUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -59,19 +59,19 @@ public class AddSubkeyWithModifiedBindingSignatureSubpacketsTest {
.done(); .done();
KeyRingInfo after = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo after = PGPainless.inspectKeyRing(secretKeys);
List<PGPPublicKey> signingKeys = after.getSigningSubkeys(); List<OpenPGPCertificate.OpenPGPComponentKey> signingKeys = after.getSigningSubkeys();
signingKeys.removeAll(before.getSigningSubkeys()); signingKeys.removeAll(before.getSigningSubkeys());
assertFalse(signingKeys.isEmpty()); assertFalse(signingKeys.isEmpty());
PGPPublicKey newKey = signingKeys.get(0); OpenPGPCertificate.OpenPGPComponentKey newKey = signingKeys.get(0);
Date newExpirationDate = after.getSubkeyExpirationDate(new OpenPgpV4Fingerprint(newKey)); Date newExpirationDate = after.getSubkeyExpirationDate(new OpenPgpV4Fingerprint(newKey.getPGPPublicKey()));
assertNotNull(newExpirationDate); assertNotNull(newExpirationDate);
Date now = new Date(); Date now = new Date();
JUtils.assertEquals( JUtils.assertEquals(
now.getTime() + MILLIS_IN_SEC * secondsUntilExpiration, now.getTime() + MILLIS_IN_SEC * secondsUntilExpiration,
newExpirationDate.getTime(), 2 * MILLIS_IN_SEC); newExpirationDate.getTime(), 2 * MILLIS_IN_SEC);
assertTrue(newKey.getSignatures().hasNext()); assertTrue(newKey.getPGPPublicKey().getSignatures().hasNext());
PGPSignature binding = newKey.getSignatures().next(); PGPSignature binding = newKey.getPGPPublicKey().getSignatures().next();
List<NotationData> notations = SignatureSubpacketsUtil.getHashedNotationData(binding); List<NotationData> notations = SignatureSubpacketsUtil.getHashedNotationData(binding);
assertEquals(1, notations.size()); assertEquals(1, notations.size());
assertEquals("test@test.test", notations.get(0).getNotationName()); assertEquals("test@test.test", notations.get(0).getNotationName());

View file

@ -4,8 +4,8 @@
package org.pgpainless.key.modification; package org.pgpainless.key.modification;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.junit.JUtils; import org.junit.JUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -28,17 +28,17 @@ public class ChangeSubkeyExpirationTimeTest {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice"); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice");
Date now = secretKeys.getPublicKey().getCreationTime(); Date now = secretKeys.getPublicKey().getCreationTime();
Date inAnHour = new Date(now.getTime() + 1000 * 60 * 60); Date inAnHour = new Date(now.getTime() + 1000 * 60 * 60);
PGPPublicKey encryptionKey = PGPainless.inspectKeyRing(secretKeys) OpenPGPCertificate.OpenPGPComponentKey encryptionKey = PGPainless.inspectKeyRing(secretKeys)
.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); .getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
secretKeys = PGPainless.modifyKeyRing(secretKeys) secretKeys = PGPainless.modifyKeyRing(secretKeys)
.setExpirationDateOfSubkey( .setExpirationDateOfSubkey(
inAnHour, inAnHour,
encryptionKey.getKeyID(), encryptionKey.getKeyIdentifier().getKeyId(),
SecretKeyRingProtector.unprotectedKeys()) SecretKeyRingProtector.unprotectedKeys())
.done(); .done();
JUtils.assertDateEquals(inAnHour, PGPainless.inspectKeyRing(secretKeys) JUtils.assertDateEquals(inAnHour, PGPainless.inspectKeyRing(secretKeys)
.getSubkeyExpirationDate(OpenPgpFingerprint.of(encryptionKey))); .getSubkeyExpirationDate(OpenPgpFingerprint.of(encryptionKey.getPGPPublicKey())));
} }
@Test @Test

View file

@ -13,8 +13,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator; import java.util.Iterator;
import org.bouncycastle.bcpg.sig.IssuerFingerprint; import org.bouncycastle.bcpg.sig.IssuerFingerprint;
@ -127,11 +125,11 @@ public class RevokeSubKeyTest {
@Test @Test
public void inspectSubpacketsOnDefaultRevocationSignature() public void inspectSubpacketsOnDefaultRevocationSignature()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { throws PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice"); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice");
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
PGPPublicKey encryptionSubkey = PGPainless.inspectKeyRing(secretKeys) PGPPublicKey encryptionSubkey = PGPainless.inspectKeyRing(secretKeys)
.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); .getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getPGPPublicKey();
secretKeys = PGPainless.modifyKeyRing(secretKeys) secretKeys = PGPainless.modifyKeyRing(secretKeys)
.revokeSubKey(encryptionSubkey.getKeyID(), protector) .revokeSubKey(encryptionSubkey.getKeyID(), protector)
@ -151,12 +149,11 @@ public class RevokeSubKeyTest {
} }
@Test @Test
public void inspectSubpacketsOnModifiedRevocationSignature() public void inspectSubpacketsOnModifiedRevocationSignature() {
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice"); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice");
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
PGPPublicKey encryptionSubkey = PGPainless.inspectKeyRing(secretKeys) PGPPublicKey encryptionSubkey = PGPainless.inspectKeyRing(secretKeys)
.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); .getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getPGPPublicKey();
secretKeys = PGPainless.modifyKeyRing(secretKeys) secretKeys = PGPainless.modifyKeyRing(secretKeys)
.revokeSubKey(encryptionSubkey.getKeyID(), protector, new RevocationSignatureSubpackets.Callback() { .revokeSubKey(encryptionSubkey.getKeyID(), protector, new RevocationSignatureSubpackets.Callback() {

View file

@ -13,8 +13,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
@ -30,11 +28,11 @@ import org.bouncycastle.bcpg.sig.RevocationKey;
import org.bouncycastle.bcpg.sig.TrustSignature; import org.bouncycastle.bcpg.sig.TrustSignature;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.CompressionAlgorithm; import org.pgpainless.algorithm.CompressionAlgorithm;
@ -52,7 +50,7 @@ import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
public class SignatureSubpacketsUtilTest { public class SignatureSubpacketsUtilTest {
@Test @Test
public void testGetKeyExpirationTimeAsDate() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { public void testGetKeyExpirationTimeAsDate() {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Expire"); .modernKeyRing("Expire");
Date expiration = Date.from(new Date().toInstant().plus(365, ChronoUnit.DAYS)); Date expiration = Date.from(new Date().toInstant().plus(365, ChronoUnit.DAYS));
@ -62,10 +60,10 @@ public class SignatureSubpacketsUtilTest {
PGPSignature expirationSig = SignaturePicker.pickCurrentUserIdCertificationSignature( PGPSignature expirationSig = SignaturePicker.pickCurrentUserIdCertificationSignature(
secretKeys, "Expire", Policy.getInstance(), new Date()); secretKeys, "Expire", Policy.getInstance(), new Date());
PGPPublicKey notTheRightKey = PGPainless.inspectKeyRing(secretKeys).getSigningSubkeys().get(0); OpenPGPCertificate.OpenPGPComponentKey notTheRightKey = PGPainless.inspectKeyRing(secretKeys).getSigningSubkeys().get(0);
assertThrows(IllegalArgumentException.class, () -> assertThrows(IllegalArgumentException.class, () ->
SignatureSubpacketsUtil.getKeyExpirationTimeAsDate(expirationSig, notTheRightKey)); SignatureSubpacketsUtil.getKeyExpirationTimeAsDate(expirationSig, notTheRightKey.getPGPPublicKey()));
} }
@Test @Test

View file

@ -14,10 +14,10 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.EncryptionPurpose; import org.pgpainless.algorithm.EncryptionPurpose;
@ -37,10 +37,11 @@ public class SubkeyAndPrimaryKeyBindingSignatureTest {
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
PGPSecretKey primaryKey = secretKeys.getSecretKey(); PGPSecretKey primaryKey = secretKeys.getSecretKey();
PGPPublicKey encryptionSubkey = info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); OpenPGPCertificate.OpenPGPComponentKey encryptionSubkey =
info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
assertNotNull(encryptionSubkey); assertNotNull(encryptionSubkey);
Set<HashAlgorithm> hashAlgorithmSet = info.getPreferredHashAlgorithms(encryptionSubkey.getKeyID()); Set<HashAlgorithm> hashAlgorithmSet = info.getPreferredHashAlgorithms(encryptionSubkey.getKeyIdentifier());
assertEquals( assertEquals(
new HashSet<>(Arrays.asList( new HashSet<>(Arrays.asList(
HashAlgorithm.SHA512, HashAlgorithm.SHA384, HashAlgorithm.SHA256, HashAlgorithm.SHA224)), HashAlgorithm.SHA512, HashAlgorithm.SHA384, HashAlgorithm.SHA256, HashAlgorithm.SHA224)),
@ -55,10 +56,10 @@ public class SubkeyAndPrimaryKeyBindingSignatureTest {
} }
}); });
PGPSignature binding = sbb.build(encryptionSubkey); PGPSignature binding = sbb.build(encryptionSubkey.getPGPPublicKey());
secretKeys = KeyRingUtils.injectCertification(secretKeys, encryptionSubkey, binding); secretKeys = KeyRingUtils.injectCertification(secretKeys, encryptionSubkey.getPGPPublicKey(), binding);
info = PGPainless.inspectKeyRing(secretKeys); info = PGPainless.inspectKeyRing(secretKeys);
assertEquals(Collections.singleton(HashAlgorithm.SHA512), info.getPreferredHashAlgorithms(encryptionSubkey.getKeyID())); assertEquals(Collections.singleton(HashAlgorithm.SHA512), info.getPreferredHashAlgorithms(encryptionSubkey.getKeyIdentifier()));
} }
} }