Merge pull request #226 from ProtonMail/feat/signature-context-streaming

Add API to sign stream with context
This commit is contained in:
marinthiercelin 2023-04-06 12:21:13 +02:00 committed by GitHub
commit 49211b24ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 38 deletions

View file

@ -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 - 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`. 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 ## [2.6.1] 2023-03-22
### Security fix ### Security fix

View file

@ -2,7 +2,6 @@ package crypto
import ( import (
"bytes" "bytes"
"crypto"
"io" "io"
"io/ioutil" "io/ioutil"
"time" "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 // If a context is provided, it is added to the signature as notation data
// with the name set in `constants.SignatureContextName`. // with the name set in `constants.SignatureContextName`.
func (keyRing *KeyRing) SignDetachedWithContext(message *PlainMessage, context *SigningContext) (*PGPSignature, error) { func (keyRing *KeyRing) SignDetachedWithContext(message *PlainMessage, context *SigningContext) (*PGPSignature, error) {
signEntity, err := keyRing.getSigningEntity() return signMessageDetached(
if err != nil { keyRing,
return nil, err message.NewReader(),
} message.IsBinary(),
var signatureNotations []*packet.Notation context,
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
} }
// VerifyDetached verifies a PlainMessage with a detached PGPSignature // VerifyDetached verifies a PlainMessage with a detached PGPSignature

View file

@ -2,7 +2,6 @@ package crypto
import ( import (
"bytes" "bytes"
"crypto"
"io" "io"
"time" "time"
@ -302,19 +301,19 @@ func (keyRing *KeyRing) DecryptSplitStream(
// SignDetachedStream generates and returns a PGPSignature for a given message Reader. // SignDetachedStream generates and returns a PGPSignature for a given message Reader.
func (keyRing *KeyRing) SignDetachedStream(message Reader) (*PGPSignature, error) { func (keyRing *KeyRing) SignDetachedStream(message Reader) (*PGPSignature, error) {
signEntity, err := keyRing.getSigningEntity() return keyRing.SignDetachedStreamWithContext(message, nil)
if err != nil {
return nil, err
} }
config := &packet.Config{DefaultHash: crypto.SHA512, Time: getTimeGenerator()} // SignDetachedStreamWithContext generates and returns a PGPSignature for a given message Reader.
var outBuf bytes.Buffer // If a context is provided, it is added to the signature as notation data
// sign bin // with the name set in `constants.SignatureContextName`.
if err := openpgp.DetachSign(&outBuf, signEntity, message, config); err != nil { func (keyRing *KeyRing) SignDetachedStreamWithContext(message Reader, context *SigningContext) (*PGPSignature, error) {
return nil, errors.Wrap(err, "gopenpgp: error in signing") return signMessageDetached(
} keyRing,
message,
return NewPGPSignature(outBuf.Bytes()), nil true,
context,
)
} }
// VerifyDetachedStream verifies a message reader with a detached PGPSignature // VerifyDetachedStream verifies a message reader with a detached PGPSignature

View file

@ -280,3 +280,36 @@ func verifySignature(
return sig, nil 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
}