From c55b9d203c2a82d6cf1e4f72136d324fdb356177 Mon Sep 17 00:00:00 2001 From: "M. Thiercelin" Date: Mon, 20 Mar 2023 11:52:52 +0100 Subject: [PATCH] Add API to sign stream with context --- CHANGELOG.md | 3 +++ crypto/keyring_message.go | 31 ++++++------------------------- crypto/keyring_streaming.go | 25 ++++++++++++------------- crypto/signature.go | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b7b774..a99f952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - When a signature fails verification because of the signature context, it returns a `SignatureVerificationError` with status `constants.SIGNATURE_BAD_CONTEXT` instead of `constants.SIGNATURE_FAILED`. +## Added +- Add api for signature context on streams `SignDetachedStreamWithContext`. + ## [2.6.1] 2023-03-22 ### Security fix diff --git a/crypto/keyring_message.go b/crypto/keyring_message.go index 6bd48a9..e3809c3 100644 --- a/crypto/keyring_message.go +++ b/crypto/keyring_message.go @@ -2,7 +2,6 @@ package crypto import ( "bytes" - "crypto" "io" "io/ioutil" "time" @@ -69,30 +68,12 @@ func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, erro // If a context is provided, it is added to the signature as notation data // with the name set in `constants.SignatureContextName`. func (keyRing *KeyRing) SignDetachedWithContext(message *PlainMessage, context *SigningContext) (*PGPSignature, error) { - signEntity, err := keyRing.getSigningEntity() - if err != nil { - return nil, err - } - var signatureNotations []*packet.Notation - if context != nil { - signatureNotations = []*packet.Notation{context.getNotation()} - } - config := &packet.Config{ - DefaultHash: crypto.SHA512, - Time: getTimeGenerator(), - SignatureNotations: signatureNotations, - } - var outBuf bytes.Buffer - if message.IsBinary() { - err = openpgp.DetachSign(&outBuf, signEntity, message.NewReader(), config) - } else { - err = openpgp.DetachSignText(&outBuf, signEntity, message.NewReader(), config) - } - if err != nil { - return nil, errors.Wrap(err, "gopenpgp: error in signing") - } - - return NewPGPSignature(outBuf.Bytes()), nil + return signMessageDetached( + keyRing, + message.NewReader(), + message.IsBinary(), + context, + ) } // VerifyDetached verifies a PlainMessage with a detached PGPSignature diff --git a/crypto/keyring_streaming.go b/crypto/keyring_streaming.go index 65f6afb..b0ba511 100644 --- a/crypto/keyring_streaming.go +++ b/crypto/keyring_streaming.go @@ -2,7 +2,6 @@ package crypto import ( "bytes" - "crypto" "io" "time" @@ -302,19 +301,19 @@ func (keyRing *KeyRing) DecryptSplitStream( // SignDetachedStream generates and returns a PGPSignature for a given message Reader. func (keyRing *KeyRing) SignDetachedStream(message Reader) (*PGPSignature, error) { - signEntity, err := keyRing.getSigningEntity() - if err != nil { - return nil, err - } + return keyRing.SignDetachedStreamWithContext(message, nil) +} - config := &packet.Config{DefaultHash: crypto.SHA512, Time: getTimeGenerator()} - var outBuf bytes.Buffer - // sign bin - if err := openpgp.DetachSign(&outBuf, signEntity, message, config); err != nil { - return nil, errors.Wrap(err, "gopenpgp: error in signing") - } - - return NewPGPSignature(outBuf.Bytes()), nil +// SignDetachedStreamWithContext generates and returns a PGPSignature for a given message Reader. +// If a context is provided, it is added to the signature as notation data +// with the name set in `constants.SignatureContextName`. +func (keyRing *KeyRing) SignDetachedStreamWithContext(message Reader, context *SigningContext) (*PGPSignature, error) { + return signMessageDetached( + keyRing, + message, + true, + context, + ) } // VerifyDetachedStream verifies a message reader with a detached PGPSignature diff --git a/crypto/signature.go b/crypto/signature.go index e376c28..d80900f 100644 --- a/crypto/signature.go +++ b/crypto/signature.go @@ -280,3 +280,36 @@ func verifySignature( return sig, nil } + +func signMessageDetached( + signKeyRing *KeyRing, + messageReader io.Reader, + isBinary bool, + context *SigningContext, +) (*PGPSignature, error) { + config := &packet.Config{ + DefaultHash: crypto.SHA512, + Time: getTimeGenerator(), + } + + signEntity, err := signKeyRing.getSigningEntity() + if err != nil { + return nil, err + } + + if context != nil { + config.SignatureNotations = append(config.SignatureNotations, context.getNotation()) + } + + var outBuf bytes.Buffer + if isBinary { + err = openpgp.DetachSign(&outBuf, signEntity, messageReader, config) + } else { + err = openpgp.DetachSignText(&outBuf, signEntity, messageReader, config) + } + if err != nil { + return nil, errors.Wrap(err, "gopenpgp: error in signing") + } + + return NewPGPSignature(outBuf.Bytes()), nil +}