From 3f33c71496d73010c679f4eff842f8cad6b439d2 Mon Sep 17 00:00:00 2001 From: Aron Wussler Date: Fri, 10 Jan 2020 20:45:41 +0100 Subject: [PATCH] Improve documentation for checking --- README.md | 32 +++++++++++++++++++++++++++----- crypto/key.go | 9 +++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 90f332a..c932986 100644 --- a/README.md +++ b/README.md @@ -327,13 +327,13 @@ A session key can be generated, encrypted to a Asymmetric/Symmetric key packet a sessionKey, err := crypto.GenerateSessionKey() -keyPacket, err := publicKey.EncryptSessionKey(sessionKey) +keyPacket, err := publicKeyRing.EncryptSessionKey(sessionKey) keyPacketSymm, err := crypto.EncryptSessionKeyWithPassword(sessionKey, password) ``` `KeyPacket` is a `[]byte` containing the session key encrypted with the private key or password. ```go -decodedKeyPacket, err := privateKey.DecryptSessionKey(keyPacket) +decodedKeyPacket, err := privateKeyRing.DecryptSessionKey(keyPacket) decodedSymmKeyPacket, err := crypto.DecryptSessionKeyWithPassword(keyPacketSymm, password) ``` `decodedKeyPacket` and `decodedSymmKeyPacket` are objects of type `*SymmetricKey` that can @@ -342,10 +342,10 @@ be used to decrypt the corresponding symmetrically encrypted data packets: ```go var message = crypto.NewPlainMessage(data) -// Encrypt data with password +// Encrypt data with session key dataPacket, err := sessionKey.Encrypt(message) -// Decrypt data with password +// Decrypt data with session key decrypted, err := sessionKey.Decrypt(password, dataPacket) //Original message in decrypted.GetBinary() @@ -362,4 +362,26 @@ pgpMessage := pgpSplitMessage.GetPGPMessage() newPGPSplitMessage, err := pgpMessage.SeparateKeyAndData() // Key Packet is in newPGPSplitMessage.GetKeyPacket() // Data Packet is in newPGPSplitMessage.GetDataPacket() -``` \ No newline at end of file +``` + +### Checking keys +In order to check that the primary key is valid the `Key#Check` function can be used. +This operation is as of 2.0.0 fairly expensive, as it requires a signature operation. +It will be improved in the future versions, and possibly expanded to the subkeys, that are +for now assumed to be correct thanks to the binding signature. +```go +const privkey = `-----BEGIN PGP PRIVATE KEY BLOCK----- +... +-----END PGP PRIVATE KEY BLOCK-----` // Encrypted private key +const passphrase = []byte("LongSecret") // Private key passphrase + +privateKeyObj, err := crypto.NewKeyFromArmored(privkey) +unlockedKeyObj = privateKeyObj.Unlock(passphrase) + +isVerified, _ := unlockedKeyObj.Check(); +if !isVerified { + // Handle broken keys +} +``` +This function runs on unlocked private keys, and it will return an error if called with public keys +or locked keys. \ No newline at end of file diff --git a/crypto/key.go b/crypto/key.go index c3e9f5a..5005ea1 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -271,6 +271,15 @@ func (key *Key) Check() (bool, error) { return false, errors.New("gopenpgp: can check only private key") } + unlocked, err := key.IsUnlocked() + if err != nil { + return false, err + } + + if !unlocked { + return false, errors.New("gopenpgp: key is not unlocked") + } + var signBuf bytes.Buffer if err = openpgp.DetachSign(&signBuf, key.entity, testReader, nil); err != nil {