mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 18:29:39 +02:00
Change type of KeyRingInfo.publicKey to OpenPGPPrimaryKey
This commit is contained in:
parent
c593b5a590
commit
137bb51f2c
2 changed files with 38 additions and 42 deletions
|
@ -43,8 +43,8 @@ class KeyRingInfo(
|
||||||
|
|
||||||
private val signatures: Signatures = Signatures(keys.pgpKeyRing, referenceDate, policy)
|
private val signatures: Signatures = Signatures(keys.pgpKeyRing, referenceDate, policy)
|
||||||
|
|
||||||
/** Primary [PGPPublicKey]. */
|
/** Primary [OpenPGPCertificate.OpenPGPPrimaryKey]. */
|
||||||
val publicKey: PGPPublicKey = keys.primaryKey.pgpPublicKey
|
val publicKey: OpenPGPCertificate.OpenPGPPrimaryKey = keys.primaryKey
|
||||||
|
|
||||||
/** Primary key ID. */
|
/** Primary key ID. */
|
||||||
val keyIdentifier: KeyIdentifier = publicKey.keyIdentifier
|
val keyIdentifier: KeyIdentifier = publicKey.keyIdentifier
|
||||||
|
@ -55,10 +55,10 @@ class KeyRingInfo(
|
||||||
val keyId: Long = keyIdentifier.keyId
|
val keyId: Long = keyIdentifier.keyId
|
||||||
|
|
||||||
/** Primary key fingerprint. */
|
/** Primary key fingerprint. */
|
||||||
val fingerprint: OpenPgpFingerprint = OpenPgpFingerprint.of(publicKey)
|
val fingerprint: OpenPgpFingerprint = OpenPgpFingerprint.of(publicKey.pgpPublicKey)
|
||||||
|
|
||||||
/** All User-IDs (valid, expired, revoked). */
|
/** All User-IDs (valid, expired, revoked). */
|
||||||
val userIds: List<String> = KeyRingUtils.getUserIdsIgnoringInvalidUTF8(publicKey)
|
val userIds: List<String> = KeyRingUtils.getUserIdsIgnoringInvalidUTF8(publicKey.pgpPublicKey)
|
||||||
|
|
||||||
/** Primary User-ID. */
|
/** Primary User-ID. */
|
||||||
val primaryUserId = keys.getPrimaryUserId(referenceDate)?.userId
|
val primaryUserId = keys.getPrimaryUserId(referenceDate)?.userId
|
||||||
|
@ -102,8 +102,7 @@ class KeyRingInfo(
|
||||||
}
|
}
|
||||||
|
|
||||||
/** List of valid public subkeys. */
|
/** List of valid public subkeys. */
|
||||||
val validSubkeys: List<PGPPublicKey> =
|
val validSubkeys: List<PGPPublicKey> = keys.getValidKeys(referenceDate).map { it.pgpPublicKey }
|
||||||
keys.publicKeys.values.filter { it.isBoundAt(referenceDate) }.map { it.pgpPublicKey }
|
|
||||||
|
|
||||||
/** 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 }
|
||||||
|
@ -136,7 +135,8 @@ class KeyRingInfo(
|
||||||
val revocationSelfSignature: PGPSignature? = signatures.primaryKeyRevocation
|
val revocationSelfSignature: PGPSignature? = signatures.primaryKeyRevocation
|
||||||
|
|
||||||
/** Public-key encryption-algorithm of the primary key. */
|
/** Public-key encryption-algorithm of the primary key. */
|
||||||
val algorithm: PublicKeyAlgorithm = PublicKeyAlgorithm.requireFromId(publicKey.algorithm)
|
val algorithm: PublicKeyAlgorithm =
|
||||||
|
PublicKeyAlgorithm.requireFromId(publicKey.pgpPublicKey.algorithm)
|
||||||
|
|
||||||
/** Creation date of the primary key. */
|
/** Creation date of the primary key. */
|
||||||
val creationDate: Date = publicKey.creationTime!!
|
val creationDate: Date = publicKey.creationTime!!
|
||||||
|
@ -178,12 +178,16 @@ class KeyRingInfo(
|
||||||
val primaryKeyExpirationDate: Date?
|
val primaryKeyExpirationDate: Date?
|
||||||
get() {
|
get() {
|
||||||
val directKeyExpirationDate: Date? =
|
val directKeyExpirationDate: Date? =
|
||||||
latestDirectKeySelfSignature?.let { getKeyExpirationTimeAsDate(it, publicKey) }
|
latestDirectKeySelfSignature?.let {
|
||||||
|
getKeyExpirationTimeAsDate(it, publicKey.pgpPublicKey)
|
||||||
|
}
|
||||||
val possiblyExpiredPrimaryUserId = getPossiblyExpiredPrimaryUserId()
|
val possiblyExpiredPrimaryUserId = getPossiblyExpiredPrimaryUserId()
|
||||||
val primaryUserIdCertification =
|
val primaryUserIdCertification =
|
||||||
possiblyExpiredPrimaryUserId?.let { getLatestUserIdCertification(it) }
|
possiblyExpiredPrimaryUserId?.let { getLatestUserIdCertification(it) }
|
||||||
val userIdExpirationDate: Date? =
|
val userIdExpirationDate: Date? =
|
||||||
primaryUserIdCertification?.let { getKeyExpirationTimeAsDate(it, publicKey) }
|
primaryUserIdCertification?.let {
|
||||||
|
getKeyExpirationTimeAsDate(it, publicKey.pgpPublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
if (latestDirectKeySelfSignature == null && primaryUserIdCertification == null) {
|
if (latestDirectKeySelfSignature == null && primaryUserIdCertification == null) {
|
||||||
throw NoSuchElementException(
|
throw NoSuchElementException(
|
||||||
|
@ -257,7 +261,7 @@ class KeyRingInfo(
|
||||||
* @return expiration date
|
* @return expiration date
|
||||||
*/
|
*/
|
||||||
fun getSubkeyExpirationDate(keyId: Long): Date? {
|
fun getSubkeyExpirationDate(keyId: Long): Date? {
|
||||||
if (publicKey.keyID == keyId) return primaryKeyExpirationDate
|
if (publicKey.keyIdentifier.keyId == keyId) return primaryKeyExpirationDate
|
||||||
val subkey =
|
val subkey =
|
||||||
getPublicKey(keyId)
|
getPublicKey(keyId)
|
||||||
?: throw NoSuchElementException(
|
?: throw NoSuchElementException(
|
||||||
|
@ -328,7 +332,7 @@ class KeyRingInfo(
|
||||||
): List<PGPPublicKey> {
|
): List<PGPPublicKey> {
|
||||||
if (userId != null && !isUserIdValid(userId)) {
|
if (userId != null && !isUserIdValid(userId)) {
|
||||||
throw UnboundUserIdException(
|
throw UnboundUserIdException(
|
||||||
OpenPgpFingerprint.of(publicKey),
|
OpenPgpFingerprint.of(publicKey.pgpPublicKey),
|
||||||
userId.toString(),
|
userId.toString(),
|
||||||
getLatestUserIdCertification(userId),
|
getLatestUserIdCertification(userId),
|
||||||
getUserIdRevocation(userId))
|
getUserIdRevocation(userId))
|
||||||
|
@ -469,7 +473,7 @@ class KeyRingInfo(
|
||||||
* @return list of key flags
|
* @return list of key flags
|
||||||
*/
|
*/
|
||||||
fun getKeyFlagsOf(keyId: Long): List<KeyFlag> =
|
fun getKeyFlagsOf(keyId: Long): List<KeyFlag> =
|
||||||
if (keyId == publicKey.keyID) {
|
if (keyId == publicKey.keyIdentifier.keyId) {
|
||||||
latestDirectKeySelfSignature?.let { sig ->
|
latestDirectKeySelfSignature?.let { sig ->
|
||||||
SignatureSubpacketsUtil.parseKeyFlags(sig)?.let { flags ->
|
SignatureSubpacketsUtil.parseKeyFlags(sig)?.let { flags ->
|
||||||
return flags
|
return flags
|
||||||
|
@ -684,7 +688,7 @@ class KeyRingInfo(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (sig.hashedSubPackets.isPrimaryUserID) {
|
if (sig.hashedSubPackets.isPrimaryUserID) {
|
||||||
getKeyExpirationTimeAsDate(sig, publicKey)?.let { expirationDate ->
|
getKeyExpirationTimeAsDate(sig, publicKey.pgpPublicKey)?.let { expirationDate ->
|
||||||
// key expired?
|
// key expired?
|
||||||
if (expirationDate < referenceDate) return false
|
if (expirationDate < referenceDate) return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,8 @@ package org.pgpainless.example;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
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;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -39,11 +35,11 @@ import org.pgpainless.util.Passphrase;
|
||||||
* The result ({@link org.pgpainless.key.generation.KeyRingBuilder}) provides some factory methods for key archetypes
|
* The result ({@link org.pgpainless.key.generation.KeyRingBuilder}) provides some factory methods for key archetypes
|
||||||
* such as {@link org.pgpainless.key.generation.KeyRingTemplates#modernKeyRing(CharSequence, String)} or
|
* such as {@link org.pgpainless.key.generation.KeyRingTemplates#modernKeyRing(CharSequence, String)} or
|
||||||
* {@link org.pgpainless.key.generation.KeyRingTemplates#simpleRsaKeyRing(CharSequence, RsaLength)}.
|
* {@link org.pgpainless.key.generation.KeyRingTemplates#simpleRsaKeyRing(CharSequence, RsaLength)}.
|
||||||
*
|
* <p>
|
||||||
* Those methods always take a user-id which is used as primary user-id, as well as a passphrase which is used to encrypt
|
* Those methods always take a user-id which is used as primary user-id, as well as a passphrase which is used to encrypt
|
||||||
* the secret key.
|
* the secret key.
|
||||||
* To generate unencrypted secret keys, just pass {@code null} as passphrase.
|
* To generate unencrypted secret keys, just pass {@code null} as passphrase.
|
||||||
*
|
* <p>
|
||||||
* Besides the archetype methods, it is possible to generate fully customized keys (see {@link #generateCustomOpenPGPKey()}).
|
* Besides the archetype methods, it is possible to generate fully customized keys (see {@link #generateCustomOpenPGPKey()}).
|
||||||
*/
|
*/
|
||||||
public class GenerateKeys {
|
public class GenerateKeys {
|
||||||
|
@ -52,12 +48,11 @@ public class GenerateKeys {
|
||||||
* This example demonstrates how to generate a modern OpenPGP key which consists of an ed25519 EdDSA primary key
|
* This example demonstrates how to generate a modern OpenPGP key which consists of an ed25519 EdDSA primary key
|
||||||
* used solely for certification of subkeys, as well as an ed25519 EdDSA signing subkey, and an X25519 ECDH
|
* used solely for certification of subkeys, as well as an ed25519 EdDSA signing subkey, and an X25519 ECDH
|
||||||
* encryption subkey.
|
* encryption subkey.
|
||||||
*
|
* <p>
|
||||||
* This is the recommended way to generate OpenPGP keys with PGPainless.
|
* This is the recommended way to generate OpenPGP keys with PGPainless.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void generateModernEcKey()
|
public void generateModernEcKey() {
|
||||||
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {
|
|
||||||
// Define a primary user-id
|
// Define a primary user-id
|
||||||
String userId = "gbaker@pgpainless.org";
|
String userId = "gbaker@pgpainless.org";
|
||||||
// Set a password to protect the secret key
|
// Set a password to protect the secret key
|
||||||
|
@ -75,7 +70,7 @@ public class GenerateKeys {
|
||||||
assertEquals(3, keyInfo.getSecretKeys().size());
|
assertEquals(3, keyInfo.getSecretKeys().size());
|
||||||
assertEquals(userId, keyInfo.getPrimaryUserId());
|
assertEquals(userId, keyInfo.getPrimaryUserId());
|
||||||
assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(),
|
assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(),
|
||||||
keyInfo.getPublicKey().getAlgorithm());
|
keyInfo.getAlgorithm().getAlgorithmId());
|
||||||
assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(),
|
assertEquals(PublicKeyAlgorithm.EDDSA_LEGACY.getAlgorithmId(),
|
||||||
keyInfo.getSigningSubkeys().get(0).getAlgorithm());
|
keyInfo.getSigningSubkeys().get(0).getAlgorithm());
|
||||||
assertEquals(PublicKeyAlgorithm.ECDH.getAlgorithmId(),
|
assertEquals(PublicKeyAlgorithm.ECDH.getAlgorithmId(),
|
||||||
|
@ -85,12 +80,11 @@ public class GenerateKeys {
|
||||||
/**
|
/**
|
||||||
* This example demonstrates how to generate a simple OpenPGP key consisting of a 4096-bit RSA key.
|
* This example demonstrates how to generate a simple OpenPGP key consisting of a 4096-bit RSA key.
|
||||||
* The RSA key is used for both signing and certifying, as well as encryption.
|
* The RSA key is used for both signing and certifying, as well as encryption.
|
||||||
*
|
* <p>
|
||||||
* This method is recommended if the application has to deal with legacy clients with poor algorithm support.
|
* This method is recommended if the application has to deal with legacy clients with poor algorithm support.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void generateSimpleRSAKey()
|
public void generateSimpleRSAKey() {
|
||||||
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
|
||||||
// Define a primary user-id
|
// Define a primary user-id
|
||||||
String userId = "mpage@pgpainless.org";
|
String userId = "mpage@pgpainless.org";
|
||||||
// Set a password to protect the secret key
|
// Set a password to protect the secret key
|
||||||
|
@ -102,19 +96,18 @@ public class GenerateKeys {
|
||||||
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
||||||
assertEquals(1, keyInfo.getSecretKeys().size());
|
assertEquals(1, keyInfo.getSecretKeys().size());
|
||||||
assertEquals(userId, keyInfo.getPrimaryUserId());
|
assertEquals(userId, keyInfo.getPrimaryUserId());
|
||||||
assertEquals(PublicKeyAlgorithm.RSA_GENERAL.getAlgorithmId(), keyInfo.getPublicKey().getAlgorithm());
|
assertEquals(PublicKeyAlgorithm.RSA_GENERAL.getAlgorithmId(), keyInfo.getAlgorithm().getAlgorithmId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This example demonstrates how to generate a simple OpenPGP key based on elliptic curves.
|
* This example demonstrates how to generate a simple OpenPGP key based on elliptic curves.
|
||||||
* The key consists of an ECDSA primary key that is used both for certification of subkeys, and signing of data,
|
* The key consists of an ECDSA primary key that is used both for certification of subkeys, and signing of data,
|
||||||
* and a single ECDH encryption subkey.
|
* and a single ECDH encryption subkey.
|
||||||
*
|
* <p>
|
||||||
* This method is recommended if small keys and high performance are desired.
|
* This method is recommended if small keys and high performance are desired.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void generateSimpleECKey()
|
public void generateSimpleECKey() {
|
||||||
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
|
||||||
// Define a primary user-id
|
// Define a primary user-id
|
||||||
String userId = "mhelms@pgpainless.org";
|
String userId = "mhelms@pgpainless.org";
|
||||||
// Set a password to protect the secret key
|
// Set a password to protect the secret key
|
||||||
|
@ -133,43 +126,42 @@ public class GenerateKeys {
|
||||||
* This example demonstrates how to generate a custom OpenPGP secret key.
|
* This example demonstrates how to generate a custom OpenPGP secret key.
|
||||||
* Among user-id and password, the user can add an arbitrary number of subkeys and specify their algorithms and
|
* Among user-id and password, the user can add an arbitrary number of subkeys and specify their algorithms and
|
||||||
* algorithm preferences.
|
* algorithm preferences.
|
||||||
*
|
* <p>
|
||||||
* If the target key amalgamation (key ring) should consist of more than just a single (sub-)key, start by providing
|
* If the target key amalgamation (key ring) should consist of more than just a single (sub-)key, start by providing
|
||||||
* the primary key specification using {@link org.pgpainless.key.generation.KeyRingBuilder#setPrimaryKey(KeySpec)}.
|
* the primary key specification using {@link org.pgpainless.key.generation.KeyRingBuilder#setPrimaryKey(KeySpec)}.
|
||||||
* Any additional subkeys can be then added using {@link org.pgpainless.key.generation.KeyRingBuilder#addSubkey(KeySpec)}.
|
* Any additional subkeys can be then added using {@link org.pgpainless.key.generation.KeyRingBuilder#addSubkey(KeySpec)}.
|
||||||
*
|
* <p>
|
||||||
* {@link KeySpec} objects can best be obtained by using the {@link KeySpec#getBuilder(KeyType, KeyFlag, KeyFlag...)}
|
* {@link KeySpec} objects can best be obtained by using the {@link KeySpec#getBuilder(KeyType, KeyFlag...)}
|
||||||
* method and providing a {@link KeyType}.
|
* method and providing a {@link KeyType}.
|
||||||
* There are a bunch of factory methods for different {@link KeyType} implementations present in {@link KeyType} itself
|
* There are a bunch of factory methods for different {@link KeyType} implementations present in {@link KeyType} itself
|
||||||
* (such as {@link KeyType#ECDH(EllipticCurve)}). {@link KeyFlag KeyFlags} determine
|
* (such as {@link KeyType#ECDH(EllipticCurve)}). {@link KeyFlag KeyFlags} determine
|
||||||
* the use of the key, like encryption, signing data or certifying subkeys.
|
* the use of the key, like encryption, signing data or certifying subkeys.
|
||||||
*
|
* <p>
|
||||||
* If you so desire, you can now specify your own algorithm preferences.
|
* If you so desire, you can now specify your own algorithm preferences.
|
||||||
* For that, see {@link org.pgpainless.key.generation.KeySpecBuilder#overridePreferredCompressionAlgorithms(CompressionAlgorithm...)},
|
* For that, see {@link org.pgpainless.key.generation.KeySpecBuilder#overridePreferredCompressionAlgorithms(CompressionAlgorithm...)},
|
||||||
* {@link org.pgpainless.key.generation.KeySpecBuilder#overridePreferredHashAlgorithms(HashAlgorithm...)} or
|
* {@link org.pgpainless.key.generation.KeySpecBuilder#overridePreferredHashAlgorithms(HashAlgorithm...)} or
|
||||||
* {@link org.pgpainless.key.generation.KeySpecBuilder#overridePreferredSymmetricKeyAlgorithms(SymmetricKeyAlgorithm...)}.
|
* {@link org.pgpainless.key.generation.KeySpecBuilder#overridePreferredSymmetricKeyAlgorithms(SymmetricKeyAlgorithm...)}.
|
||||||
*
|
* <p>
|
||||||
* Note, that if you set preferred algorithms, the preference lists are sorted from high priority to low priority.
|
* Note, that if you set preferred algorithms, the preference lists are sorted from high priority to low priority.
|
||||||
*
|
* <p>
|
||||||
* When setting the primary key spec ({@link org.pgpainless.key.generation.KeyRingBuilder#setPrimaryKey(KeySpecBuilder)}),
|
* When setting the primary key spec ({@link org.pgpainless.key.generation.KeyRingBuilder#setPrimaryKey(KeySpecBuilder)}),
|
||||||
* make sure that the primary key spec has the {@link KeyFlag} {@link KeyFlag#CERTIFY_OTHER} set, as this is a requirement
|
* make sure that the primary key spec has the {@link KeyFlag} {@link KeyFlag#CERTIFY_OTHER} set, as this is a requirement
|
||||||
* for primary keys.
|
* for primary keys.
|
||||||
*
|
* <p>
|
||||||
* Furthermore, you have to set at least the primary user-id via
|
* Furthermore, you have to set at least the primary user-id via
|
||||||
* {@link org.pgpainless.key.generation.KeyRingBuilder#addUserId(String)},
|
* {@link org.pgpainless.key.generation.KeyRingBuilder#addUserId(CharSequence)},
|
||||||
* but you can also add additional user-ids.
|
* but you can also add additional user-ids.
|
||||||
*
|
* <p>
|
||||||
* If you want the key to expire at a certain point in time, call
|
* If you want the key to expire at a certain point in time, call
|
||||||
* {@link org.pgpainless.key.generation.KeyRingBuilder#setExpirationDate(Date)}.
|
* {@link org.pgpainless.key.generation.KeyRingBuilder#setExpirationDate(Date)}.
|
||||||
* Lastly you can decide whether to set a passphrase to protect the secret key using
|
* Lastly you can decide whether to set a passphrase to protect the secret key using
|
||||||
* {@link org.pgpainless.key.generation.KeyRingBuilder#setPassphrase(Passphrase)}.
|
* {@link org.pgpainless.key.generation.KeyRingBuilder#setPassphrase(Passphrase)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void generateCustomOpenPGPKey()
|
public void generateCustomOpenPGPKey() {
|
||||||
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
|
||||||
// Instead of providing a string, we can assemble a user-id by using the user-id builder.
|
// Instead of providing a string, we can assemble a user-id by using the user-id builder.
|
||||||
// The example below corresponds to "Morgan Carpenter (Pride!) <mcarpenter@pgpainless.org>"
|
// The example below corresponds to "Morgan Carpenter (Pride!) <mcarpenter@pgpainless.org>"
|
||||||
UserId userId = UserId.newBuilder()
|
UserId userId = UserId.builder()
|
||||||
.withName("Morgan Carpenter")
|
.withName("Morgan Carpenter")
|
||||||
.withEmail("mcarpenter@pgpainless.org")
|
.withEmail("mcarpenter@pgpainless.org")
|
||||||
.withComment("Pride!")
|
.withComment("Pride!")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue