Add KeyRingInfo.isUsableForEncryption()

This commit is contained in:
Paul Schaub 2022-03-06 14:58:36 +01:00
parent afad3fc747
commit 5b9e72d42c
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
2 changed files with 118 additions and 1 deletions

View File

@ -1009,6 +1009,25 @@ public class KeyRingInfo {
return new KeyAccessor.SubKey(this, new SubkeyIdentifier(keys, keyId)).getPreferredCompressionAlgorithms();
}
/**
* Returns true, if the certificate has at least one usable encryption subkey.
*
* @return true if usable for encryption
*/
public boolean isUsableForEncryption() {
return isUsableForEncryption(EncryptionPurpose.ANY);
}
/**
* Returns true, if the certificate has at least one usable encryption subkey for the given purpose.
*
* @param purpose purpose of encryption
* @return true if usable for encryption
*/
public boolean isUsableForEncryption(@Nonnull EncryptionPurpose purpose) {
return !getEncryptionSubkeys(purpose).isEmpty();
}
private KeyAccessor getKeyAccessor(@Nullable String userId, long keyID) {
if (getPublicKey(keyID) == null) {
throw new NoSuchElementException("No subkey with key id " + Long.toHexString(keyID) + " found on this key.");

View File

@ -218,7 +218,7 @@ public class KeyRingInfoTest {
PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing()
.setPrimaryKey(KeySpec.getBuilder(
KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER))
KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER))
.addSubkey(KeySpec.getBuilder(
KeyType.ECDH(EllipticCurve._BRAINPOOLP384R1),
KeyFlag.ENCRYPT_STORAGE))
@ -758,4 +758,102 @@ public class KeyRingInfoTest {
List<String> emails = info.getEmailAddresses();
assertEquals(emails, Arrays.asList("alice@email.tld", "alice@pgpainless.org", "alice@openpgp.org", "alice@rfc4880.spec"));
}
@Test
public void isUsableForEncryptionTest_base() throws IOException {
String CERT = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"Version: PGPainless\n" +
"Comment: 9B6A C43E A67C 11BB C023 4CC3 69D5 9A7C 29C0 F858\n" +
"Comment: Usable <usable@pgpainless.org>\n" +
"\n" +
"mDMEYiS54BYJKwYBBAHaRw8BAQdAr0FXsDQtIpF54UwfjQb+8XJ3jxt3LkpCh0e7\n" +
"lH59Vzy0HlVzYWJsZSA8dXNhYmxlQHBncGFpbmxlc3Mub3JnPoiPBBMWCgBBBQJi\n" +
"JLngCRBp1Zp8KcD4WBYhBJtqxD6mfBG7wCNMw2nVmnwpwPhYAp4BApsBBRYCAwEA\n" +
"BAsJCAcFFQoJCAsCmQEAACuNAQDX+7/ffM2B9qaW+F9MkeUJeq9u8MLk+BcaotQZ\n" +
"/c+8pQD/RhaVmKTLjm+RmpG2O1lrkta4L5CQQBXYdNMnebhlLAu4OARiJLngEgor\n" +
"BgEEAZdVAQUBAQdA8Et257jQXR0oJOimAWU9Z5Erq5OcfguBI28ixgw5z2IDAQgH\n" +
"iHUEGBYKAB0FAmIkueACngECmwwFFgIDAQAECwkIBwUVCgkICwAKCRBp1Zp8KcD4\n" +
"WDQYAQDtJG06gAiFk7D1EqdtoTgBeIXi6pdKJ8VQA17/Sel1PgEAjO7Gy+RishFG\n" +
"eT0WwimGAGWOFgyIB8GCmuk1sEN+9wO4MwRiJLngFgkrBgEEAdpHDwEBB0BNGWZx\n" +
"IiCzs6Acu/e7Di9E+uUZmEA7geObWgwPleedLYjVBBgWCgB9BQJiJLngAp4BApsC\n" +
"BRYCAwEABAsJCAcFFQoJCAtfIAQZFgoABgUCYiS54AAKCRBsyz3UPPzzw6bTAQCZ\n" +
"4NnXfhuyw2itPKNnVSvPl72GgHzfVb2MZi2QBPFJyQD+K7Xl6qNcaI9VyMos8zSy\n" +
"VT74iE7Sraqu2Fck27y1wgMACgkQadWafCnA+FjLFwEAxb/GFdAoUgmY6DGIbatO\n" +
"LOIorswrgSQVZ8B1yLh1gxcA/2K3XO1Tl68O961SW60CijoBY/16EFC+mkQIzxTT\n" +
"J5wP\n" +
"=nFoO\n" +
"-----END PGP PUBLIC KEY BLOCK-----";
PGPPublicKeyRing cert = PGPainless.readKeyRing().publicKeyRing(CERT);
KeyRingInfo info = PGPainless.inspectKeyRing(cert);
assertTrue(info.isUsableForEncryption());
}
@Test
public void isUsableForEncryptionTest_commsOnly() throws IOException {
String CERT = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"Version: PGPainless\n" +
"Comment: B2EE 493D 1DAC 943A 1CBD B151 5F15 42D1 ACB7 D26F\n" +
"Comment: Comms Only <comms-only@pgpainless.org>\n" +
"\n" +
"mG8EYiS7mhMFK4EEACIDAwTENCF226L9l1i24ZpHuTK9P9kEc7neMZ1cQbJFSX9p\n" +
"ZP89dp4dnjZcAop5jzdvqjU98BgX9STZB6q2qYEG46luZoanDA0dpwzm0TENAvcr\n" +
"KoeIMqjv6dkKs5k11qtFx/K0JkNvbW1zIE9ubHkgPGNvbW1zLW9ubHlAcGdwYWlu\n" +
"bGVzcy5vcmc+iK8EExMKAEEFAmIku5sJEF8VQtGst9JvFiEEsu5JPR2slDocvbFR\n" +
"XxVC0ay30m8CngECmwMFFgIDAQAECwkIBwUVCgkICwKZAQAA3u4BgOl888SnxXys\n" +
"Ft/sPRh/hT8n0ObrxDHUgaAR5J7Sc3097u1r3ecCYaY045FYKKb23QGAjGSEEFG1\n" +
"TLbM1JMsE5H7xjjjJ5tTM6l45vkkrk3uMhsCL+QLv9pp251ctTF/JSCvuHMEYiS7\n" +
"mxIFK4EEACIDAwToE6c42GWSI0zmalisYewWvV/2Sfdo9KKgxfzX3rfldrOWFkN1\n" +
"fkLy6b01AUt3RqfwEBIJK6OrSXOlmdCiRV1Oqf20f2MGsDNXAttDApSSDJIHwV24\n" +
"3i6qylin0ujQ9KIDAQgHiJUEGBMKAB0FAmIku5sCngECmwQFFgIDAQAECwkIBwUV\n" +
"CgkICwAKCRBfFULRrLfSbwoYAYCzcZ29xIRUEHzZvAXWeHselBLdLGztZSBZKd9T\n" +
"m045mewePa780jk5o2z5Nt4Bj0EBfRxoiWt/czpy0nWpyfEeTHOx32jHHoTStjIF\n" +
"2XO/hpB2T8VXFfFKwj7U9LGkX+ciLg==\n" +
"=etPP\n" +
"-----END PGP PUBLIC KEY BLOCK-----";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(CERT);
KeyRingInfo info = PGPainless.inspectKeyRing(publicKeys);
assertTrue(info.isUsableForEncryption(EncryptionPurpose.COMMUNICATIONS));
assertTrue(info.isUsableForEncryption(EncryptionPurpose.ANY));
assertFalse(info.isUsableForEncryption(EncryptionPurpose.STORAGE));
}
@Test
public void isUsableForEncryptionTest_encryptionKeyRevoked() throws IOException {
// encryption subkey is revoked
String CERT = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"Version: PGPainless\n" +
"Comment: CE65 608D 8639 E20C 61BF 077B F010 3226 1C64 5EA7\n" +
"Comment: Revoked <revoked@pgpainless.org>\n" +
"\n" +
"mDMEYiS8+hYJKwYBBAHaRw8BAQdATvSKAaY5yvyOdJtZXBEXbyiWSsExOwnP2L35\n" +
"AyMPe7u0IFJldm9rZWQgPHJldm9rZWRAcGdwYWlubGVzcy5vcmc+iI8EExYKAEEF\n" +
"AmIkvPoJEPAQMiYcZF6nFiEEzmVgjYY54gxhvwd78BAyJhxkXqcCngECmwEFFgID\n" +
"AQAECwkIBwUVCgkICwKZAQAAYFQA/02fMgRnneYK17Vsxc8DJEj0pVmTDHIOQH8K\n" +
"O8BuTkvhAP9zXtnJ7BsWO3Kg/ajIlaZEzMl6/lK2FTnAzBhs1UtrD7g4BGIkvPoS\n" +
"CisGAQQBl1UBBQEBB0AO8Bzm66ydlFhKtesh9EX66k4yyODeO0X3y3JUbrAnFQMB\n" +
"CAeIdQQYFgoAHQUCYiS8+gKeAQKbDAUWAgMBAAQLCQgHBRUKCQgLAAoJEPAQMiYc\n" +
"ZF6nTB0BAPjF6pUUrS3wv8CvrIM3S4BCtCOp+oQyPsie72As+47SAP41KfnvzYF3\n" +
"Y0WBp94Dqiy1MkvMZ9Q2x8BQt/L1UsoTBIh7BCgWCgAtBQJiJLz8CRDwEDImHGRe\n" +
"pxYhBM5lYI2GOeIMYb8He/AQMiYcZF6nAocAAh0DAAABqgD/TJpSDZ5fX3zNHqmN\n" +
"4TOuJ1GEkiYpPjBhem2C+U9jHjoBAJxQqzDB2VMiUDfe2+LLVIYa4EwhT2rT12qg\n" +
"aJ+TXWAJuDMEYiS8+hYJKwYBBAHaRw8BAQdAR0y6K6GPt4ddNyaRX16duqDFZwQi\n" +
"jeflFZ+UGLQ5GgSI1QQYFgoAfQUCYiS8+gKeAQKbAgUWAgMBAAQLCQgHBRUKCQgL\n" +
"XyAEGRYKAAYFAmIkvPoACgkQCX8koK2POrbPywEA3mbeGX8vWwnENtiFeMBjXNox\n" +
"oHAIuULBsvOdc1xrH0QBALezsulAJoziQ/t+EUrNHgTELDq3F8Y8tmLAJykb/nQB\n" +
"AAoJEPAQMiYcZF6n6CAA/0HadYoqOUbMjgu3Tle0HSXiTCJfBrTox5trTOKUsQ8z\n" +
"AQCjeV+3VT+u1movwIYv4XkzB6gB+B2C+DK9nvG5sXZhBg==\n" +
"=uqmO\n" +
"-----END PGP PUBLIC KEY BLOCK-----";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(CERT);
KeyRingInfo info = PGPainless.inspectKeyRing(publicKeys);
assertFalse(info.isUsableForEncryption());
assertFalse(info.isUsableForEncryption(EncryptionPurpose.ANY));
assertFalse(info.isUsableForEncryption(EncryptionPurpose.COMMUNICATIONS));
assertFalse(info.isUsableForEncryption(EncryptionPurpose.STORAGE));
}
}