diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java index 9884f654..01f93d0b 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java @@ -1,5 +1,6 @@ /* * Copyright 2021 Paul Schaub. + * Copyright 2021 Flowcrypt a.s. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,6 +63,16 @@ public class KeyInfo { return secretKey == null || isDecrypted(secretKey); } + /** + * Returns indication that a contained secret key has S2K of a type GNU_DUMMY_S2K. + * + * @return true if secret key has S2K of a type GNU_DUMMY_S2K, false if there is public key only, + * or S2K on the secret key is absent or not of a type GNU_DUMMY_S2K. + */ + public boolean hasGnuDummyS2K() { + return secretKey != null && hasGnuDummyS2K(secretKey); + } + public static String getCurveName(PGPPublicKey publicKey) { PublicKeyAlgorithm algorithm = PublicKeyAlgorithm.fromId(publicKey.getAlgorithm()); ECPublicBCPGKey key; @@ -95,7 +106,7 @@ public class KeyInfo { * @return true if secret key is encrypted, false otherwise. */ public static boolean isEncrypted(PGPSecretKey secretKey) { - return secretKey.getS2KUsage() != 0 && secretKey.getS2K().getType() != S2K.GNU_DUMMY_S2K; + return secretKey.getS2KUsage() != 0; } /** @@ -105,6 +116,17 @@ public class KeyInfo { * @return true if secret key is encrypted, false otherwise. */ public static boolean isDecrypted(PGPSecretKey secretKey) { - return secretKey.getS2KUsage() == 0 || secretKey.getS2K().getType() == S2K.GNU_DUMMY_S2K; + return secretKey.getS2KUsage() == 0; + } + + /** + * Returns indication that a secret key has S2K of a type GNU_DUMMY_S2K. + * + * @param secretKey A secret key to examine. + * @return true if secret key has S2K of a type GNU_DUMMY_S2K, false otherwise. + */ + public static boolean hasGnuDummyS2K(PGPSecretKey secretKey) { + final S2K s2k = secretKey.getS2K(); + return s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K; } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java index c0ab9759..3788d5af 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java @@ -1,5 +1,6 @@ /* * Copyright 2020 Paul Schaub. + * Copyright 2021 Flowcrypt a.s. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -297,16 +298,17 @@ public class KeyRingInfo { } /** - * Return true when every secret key on the key ring is not encrypted. - * If there is at least one encrypted secret key on the ring, return false. - * If the ring is a {@link PGPPublicKeyRing}, return true. + * Returns true when every secret key on the key ring is not encrypted. + * If there is at least one encrypted secret key on the key ring, returns false. + * If the key ring is a {@link PGPPublicKeyRing}, returns true. + * Sub-keys with S2K of a type GNU_DUMMY_S2K do not affect the result. * * @return true if all secret keys are unencrypted. */ public boolean isFullyDecrypted() { if (isSecretKey()) { for (PGPSecretKey secretKey : getSecretKeys()) { - if (KeyInfo.isEncrypted(secretKey)) { + if (!KeyInfo.hasGnuDummyS2K(secretKey) && KeyInfo.isEncrypted(secretKey)) { return false; } } @@ -316,15 +318,16 @@ public class KeyRingInfo { /** * Returns true when every secret key on the key ring is encrypted. - * If there is at least one not encrypted secret key on the ring, return false. - * If the ring is a {@link PGPPublicKeyRing}, return false. + * If there is at least one not encrypted secret key on the key ring, returns false. + * If the key ring is a {@link PGPPublicKeyRing}, returns false. + * Sub-keys with S2K of a type GNU_DUMMY_S2K do not affect a result. * * @return true if all secret keys are encrypted. */ public boolean isFullyEncrypted() { if (isSecretKey()) { for (PGPSecretKey secretKey : getSecretKeys()) { - if (KeyInfo.isDecrypted(secretKey)) { + if (!KeyInfo.hasGnuDummyS2K(secretKey) && KeyInfo.isDecrypted(secretKey)) { return false; } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java index b02b182c..5725bbc2 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java @@ -1,5 +1,6 @@ /* * Copyright 2020 Paul Schaub. + * Copyright 2021 Flowcrypt a.s. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.