Problem statement
NCC Group found a (known) footgun in our API:
The library does not prevent a user from manually populating the signature field or modifying the protected header after calling Sign() to potentially violate this requirement.
Example:
msg, _ := cose.Sign1(rand.Reader, signer, protected, []byte("hello world"), nil)
msg.Signature = []byte("footgun!") // <-------
sig, _ := msg.MarshalCBOR()
The same applies to Verify():
var msg cose.Sign1Message
msg.UnmarshalCBOR(sig)
msg.Signature = nil // <------- footgun
msg.Verify(nil, verifier)
We initially added Sign1 and Verify1 to make it easier to sign and verify messages, but with the current signature they don't prevent user to misuse go-cose.
Proposal
Me proposal is to change these two functions so they don't work with Sign1Message but just deal with cbor-marshaled messages:
func Sign1(rand io.Reader, signer Signer, header Headers, payload []byte, external []byte) (cbor_msg []byte, err error)
func Verify1(verifier Verifier, cbor_msg []byte, external []byte) error
With this change, users that don't need the flexibility of Sign1Message won't need to even know it exist, as the signature would be represented an opaque, difficult-to-misuse, []byte.
Worth nothing that users can still misuse Sign1Message.Sign() and Sign1Message.Verify(), but keeping them as-is allow advanced users to do their custom marshalling or validations.
Edited: Update Sign1 proposed API.
Edit2: Notice that the proposed signature is very similar to .Net's static CoseSign1Message.Sign(...).
Edit3: Verify1 is proposed to be removed as per thread discussion.
Problem statement
NCC Group found a (known) footgun in our API:
Example:
The same applies to
Verify():We initially added
Sign1andVerify1to make it easier to sign and verify messages, but with the current signature they don't prevent user to misusego-cose.Proposal
Me proposal is to change these two functions so they don't work with
Sign1Messagebut just deal with cbor-marshaled messages:func Verify1(verifier Verifier, cbor_msg []byte, external []byte) errorWith this change, users that don't need the flexibility of
Sign1Messagewon't need to even know it exist, as the signature would be represented an opaque, difficult-to-misuse,[]byte.Worth nothing that users can still misuse
Sign1Message.Sign()andSign1Message.Verify(), but keeping them as-is allow advanced users to do their custom marshalling or validations.Edited: Update
Sign1proposed API.Edit2: Notice that the proposed signature is very similar to .Net's static CoseSign1Message.Sign(...).
Edit3:
Verify1is proposed to be removed as per thread discussion.