From 3dd1711707c052f97bc53cd3be2dd690e12452b2 Mon Sep 17 00:00:00 2001 From: Aditya Wasan Date: Fri, 9 Apr 2021 16:02:10 +0530 Subject: [PATCH] Add methods to get key capabilities (#125) * Add methods to get key capabilities Signed-off-by: Aditya Wasan * Use correct indetity to check for flags Signed-off-by: Aditya Wasan * Fix lint Signed-off-by: Aditya Wasan * Remove CanCertify and update CanSign to use SigningKey Signed-off-by: GitHub * keyring: implement CanSign and CanEncrypt Signed-off-by: GitHub * key/keyring: add tests for key capabilities Signed-off-by: GitHub * Apply suggestions from code review Renames CanSign to CanVerify and adds an extended test for public-only keys to confirm CanVerify is true for them. Co-authored-by: wussler Co-authored-by: Harsh Shandilya Co-authored-by: wussler --- crypto/key.go | 12 ++++++++++++ crypto/key_test.go | 15 +++++++++++++++ crypto/keyring.go | 22 ++++++++++++++++++++++ crypto/keyring_test.go | 9 +++++++++ 4 files changed, 58 insertions(+) diff --git a/crypto/key.go b/crypto/key.go index e5231a6..49af11e 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -251,6 +251,18 @@ func (key *Key) GetPublicKey() (b []byte, err error) { // --- Key object properties +// CanVerify returns true if any of the subkeys can be used for verification. +func (key *Key) CanVerify() bool { + _, canVerify := key.entity.SigningKey(getNow()) + return canVerify +} + +// CanEncrypt returns true if any of the subkeys can be used for encryption. +func (key *Key) CanEncrypt() bool { + _, canEncrypt := key.entity.EncryptionKey(getNow()) + return canEncrypt +} + // IsExpired checks whether the key is expired. func (key *Key) IsExpired() bool { _, ok := key.entity.EncryptionKey(getNow()) diff --git a/crypto/key_test.go b/crypto/key_test.go index b6faaef..cae280e 100644 --- a/crypto/key_test.go +++ b/crypto/key_test.go @@ -410,3 +410,18 @@ func TestToPublic(t *testing.T) { assert.False(t, publicKey.IsPrivate()) assert.True(t, privateKey.IsPrivate()) } + +func TestKeyCapabilities(t *testing.T) { + assert.True(t, keyTestEC.CanVerify()) + assert.True(t, keyTestEC.CanEncrypt()) + assert.True(t, keyTestRSA.CanVerify()) + assert.True(t, keyTestRSA.CanEncrypt()) + + publicKey, err := keyTestEC.ToPublic() + if err != nil { + t.Fatal("Cannot make key public:", err) + } + + assert.True(t, publicKey.CanVerify()) + assert.True(t, publicKey.CanEncrypt()) +} diff --git a/crypto/keyring.go b/crypto/keyring.go index 774b160..201f5ee 100644 --- a/crypto/keyring.go +++ b/crypto/keyring.go @@ -114,6 +114,28 @@ func (keyRing *KeyRing) GetIdentities() []*Identity { return identities } +// CanVerify returns true if any of the keys in the keyring can be used for verification. +func (keyRing *KeyRing) CanVerify() bool { + keys := keyRing.GetKeys() + for _, key := range keys { + if key.CanVerify() { + return true + } + } + return false +} + +// CanEncrypt returns true if any of the keys in the keyring can be used for encryption. +func (keyRing *KeyRing) CanEncrypt() bool { + keys := keyRing.GetKeys() + for _, key := range keys { + if key.CanEncrypt() { + return true + } + } + return false +} + // GetKeyIDs returns array of IDs of keys in this KeyRing. func (keyRing *KeyRing) GetKeyIDs() []uint64 { var res = make([]uint64, len(keyRing.entities)) diff --git a/crypto/keyring_test.go b/crypto/keyring_test.go index e64d880..9f8c765 100644 --- a/crypto/keyring_test.go +++ b/crypto/keyring_test.go @@ -222,3 +222,12 @@ func TestEncryptedDetachedSignature(t *testing.T) { t.Fatal("Expected an error while verifying bad encSignature, got nil") } } + +func TestKeyringCapabilities(t *testing.T) { + assert.True(t, keyRingTestPrivate.CanVerify()) + assert.True(t, keyRingTestPrivate.CanEncrypt()) + assert.True(t, keyRingTestPublic.CanVerify()) + assert.True(t, keyRingTestPublic.CanEncrypt()) + assert.True(t, keyRingTestMultiple.CanVerify()) + assert.True(t, keyRingTestMultiple.CanEncrypt()) +}