diff --git a/README.md b/README.md index 7bc087d..733d54c 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,15 @@ Construct a new COSE_Sign1 message, then sign it using ECDSA w/ SHA-512 and fina privateKey, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) signer, _ := cose.NewSigner(cose.AlgorithmES512, privateKey) -// create message to be signed -msgToSign := cose.NewSign1Message() -msgToSign.Payload = []byte("hello world") -msgToSign.Headers.Protected.SetAlgorithm(cose.AlgorithmES512) - -// sign message -_ = msgToSign.Sign(rand.Reader, nil, signer) - -// marshal message -data, _ := msgToSign.MarshalCBOR() +// create message header +headers := cose.Headers{ + Protected: cose.ProtectedHeader{ + cose.HeaderLabelAlgorithm: cose.AlgorithmES512, + }, +} + +// sign and marshal message +sig, _ := cose.Sign1(rand.Reader, signer, headers, []byte("hello world"), nil) ``` Verify a raw COSE_Sign1 message. For example: diff --git a/example_test.go b/example_test.go index 91efa45..b007b61 100644 --- a/example_test.go +++ b/example_test.go @@ -1,7 +1,6 @@ package cose_test import ( - "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -153,79 +152,21 @@ func ExampleSign1() { } // sign message - protected := cose.ProtectedHeader{} - protected.SetAlgorithm(cose.AlgorithmES512) - msg, err := cose.Sign1(rand.Reader, signer, protected, []byte("hello world"), nil) - if err != nil { - panic(err) + headers := cose.Headers{ + Protected: cose.ProtectedHeader{ + cose.HeaderLabelAlgorithm: cose.AlgorithmES512, + }, + Unprotected: cose.UnprotectedHeader{ + cose.HeaderLabelKeyID: 1, + }, } - - // update unprotected headers - msg.Headers.Unprotected[cose.HeaderLabelKeyID] = 1 - - // encode message - sig, err := msg.MarshalCBOR() + sig, err := cose.Sign1(rand.Reader, signer, headers, []byte("hello world"), nil) if err != nil { panic(err) } + fmt.Println("message signed") - _ = sig // futher process on sig + _ = sig // further process on sig // Output: // message signed } - -// This example demonstrates verifying COSE_Sign1 signatures using Verify1(). -func ExampleVerify1() { - // get a signed message and a trusted public key - sig, publicKey := getSignatureAndPublicKey() - - // create a verifier from a trusted public key - verifier, err := cose.NewVerifier(cose.AlgorithmES512, publicKey) - if err != nil { - panic(err) - } - - // verify message - var msg cose.Sign1Message - err = msg.UnmarshalCBOR(sig) - if err != nil { - panic(err) - } - err = cose.Verify1(&msg, nil, verifier) - if err != nil { - panic(err) - } - fmt.Println("message verified") - - // tamper the message and verification should fail - msg.Payload = []byte("foobar") - err = cose.Verify1(&msg, nil, verifier) - if err != cose.ErrVerification { - panic(err) - } - fmt.Println("verification error as expected") - // Output: - // message verified - // verification error as expected -} - -// getSignatureAndPublicKey is a helping function for ExampleVerify1(). -func getSignatureAndPublicKey() ([]byte, crypto.PublicKey) { - privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - if err != nil { - panic(err) - } - signer, err := cose.NewSigner(cose.AlgorithmES512, privateKey) - if err != nil { - panic(err) - } - msgToSign, err := cose.Sign1(rand.Reader, signer, nil, []byte("hello world"), nil) - if err != nil { - panic(err) - } - sig, err := msgToSign.MarshalCBOR() - if err != nil { - panic(err) - } - return sig, privateKey.Public() -} diff --git a/fuzz_test.go b/fuzz_test.go index 5bf9bda..e8f2b7b 100644 --- a/fuzz_test.go +++ b/fuzz_test.go @@ -129,15 +129,19 @@ func FuzzSign1(f *testing.F) { if err != nil { t.Fatal(err) } - msg, err := cose.Sign1(rand.Reader, signer, hdr, payload, external) + msg := cose.Sign1Message{ + Headers: cose.Headers{Protected: hdr}, + Payload: payload, + } + err = msg.Sign(rand.Reader, external, signer) if err != nil { t.Fatal(err) } - err = cose.Verify1(msg, external, verifier) + err = msg.Verify(external, verifier) if err != nil { t.Fatal(err) } - err = cose.Verify1(msg, append(external, []byte{0}...), verifier) + err = msg.Verify(append(external, []byte{0}...), verifier) if err == nil { t.Fatal("verification error expected") } diff --git a/sign1.go b/sign1.go index 9d8606f..8bac555 100644 --- a/sign1.go +++ b/sign1.go @@ -227,30 +227,14 @@ func (m *Sign1Message) digestToBeSigned(alg Algorithm, external []byte) ([]byte, // This method is a wrapper of `Sign1Message.Sign()`. // // Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4 -func Sign1(rand io.Reader, signer Signer, protected ProtectedHeader, payload, external []byte) (*Sign1Message, error) { - if protected == nil { - protected = ProtectedHeader{} - } - msg := &Sign1Message{ - Headers: Headers{ - Protected: protected, - Unprotected: UnprotectedHeader{}, - }, +func Sign1(rand io.Reader, signer Signer, headers Headers, payload []byte, external []byte) ([]byte, error) { + msg := Sign1Message{ + Headers: headers, Payload: payload, } err := msg.Sign(rand, external, signer) if err != nil { return nil, err } - return msg, nil -} - -// Verify1 verifies a Sign1Message returning nil on success or a suitable error -// if verification fails. -// -// This method is a wrapper of `Sign1Message.Verify()`. -// -// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4 -func Verify1(msg *Sign1Message, external []byte, verifier Verifier) error { - return msg.Verify(external, verifier) + return msg.MarshalCBOR() }