diff --git a/go.mod b/go.mod index 0e73d4dec5..811684d6be 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/vbatts/tar-split v0.11.3 // indirect github.com/vektah/gqlparser/v2 v2.4.5 // indirect - github.com/veraison/go-cose v1.0.0 // indirect + github.com/veraison/go-cose v1.1.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect diff --git a/go.sum b/go.sum index c4a2aed40f..cef792149d 100644 --- a/go.sum +++ b/go.sum @@ -995,8 +995,8 @@ github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RV github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/vektah/gqlparser/v2 v2.4.5 h1:C02NsyEsL4TXJB7ndonqTfuQOL4XPIu0aAWugdmTgmc= github.com/vektah/gqlparser/v2 v2.4.5/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0= -github.com/veraison/go-cose v1.0.0 h1:Jxirc0rl3gG7wUFgW+82tBQNeK8T8e2Bk1Vd298ob4A= -github.com/veraison/go-cose v1.0.0/go.mod h1:7ziE85vSq4ScFTg6wyoMXjucIGOf4JkFEZi/an96Ct4= +github.com/veraison/go-cose v1.1.0 h1:AalPS4VGiKavpAzIlBjrn7bhqXiXi4jbMYY/2+UC+4o= +github.com/veraison/go-cose v1.1.0/go.mod h1:7ziE85vSq4ScFTg6wyoMXjucIGOf4JkFEZi/an96Ct4= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= diff --git a/vendor/github.com/veraison/go-cose/CODEOWNERS b/vendor/github.com/veraison/go-cose/CODEOWNERS new file mode 100644 index 0000000000..767969e2a9 --- /dev/null +++ b/vendor/github.com/veraison/go-cose/CODEOWNERS @@ -0,0 +1,4 @@ +# To be kept in sync with: [community/OWNERS](https://github.com/veraison/community/blob/main/OWNERS) +# and the GitHub Team: [go-cose-maintainers](https://github.com/orgs/veraison/teams/go-cose-maintainers) + +* henkbirkholz qmuntal roywill setrofim shizhMSFT simonfrost-arm SteveLasker thomas-fossati yogeshbdeshpande diff --git a/vendor/github.com/veraison/go-cose/CODE_OF_CONDUCT.md b/vendor/github.com/veraison/go-cose/CODE_OF_CONDUCT.md deleted file mode 100644 index 498baa3fb0..0000000000 --- a/vendor/github.com/veraison/go-cose/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,15 +0,0 @@ -# Community Participation Guidelines - -This repository is governed by Mozilla's code of conduct and etiquette guidelines. -For more details, please read the -[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). - -## How to Report -For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page. - - diff --git a/vendor/github.com/veraison/go-cose/README.md b/vendor/github.com/veraison/go-cose/README.md index d3de617824..74a8f7735f 100644 --- a/vendor/github.com/veraison/go-cose/README.md +++ b/vendor/github.com/veraison/go-cose/README.md @@ -8,12 +8,31 @@ A golang library for the [COSE specification][cose-spec] ## Project Status -**Current Release**: [go-cose rc 1][release-rc-1] +**Current Release**: [go-cose v1.0.0][current-release] The project was *initially* forked from the upstream [mozilla-services/go-cose][mozilla-go-cose] project, however the Veraison and Mozilla maintainers have agreed to retire the mozilla-services/go-cose project and focus on [veraison/go-cose][veraison-go-cose] as the active project. We thank the [Mozilla maintainers and contributors][mozilla-contributors] for their great work that formed the base of the [veraison/go-cose][veraison-go-cose] project. +## Community + +The [veraison/go-cose](https://github.com/veraison/go-cose) project is an open source community effort. + +You can reach the go-cose community via:: + +- [Mailing List](veraison-project@confidentialcomputing.io) +- Bi-weekly meetings: 08:00-09:00 Pacific + - [Zoom meeting link](https://us02web.zoom.us/j/81054434992?pwd=YjNBU21seU5VcGdtVXY3VHVjS251Zz09) + - [Calendar ics link](https://zoom.us/meeting/tZUtcu2srT8jE9YFubXn-lC9upuwUiiev52G/ics) +- [Meeting Notes](https://veraison.zulipchat.com/#narrow/stream/317999-go-cose-meetings) +- [Meeting Recordings](https://www.youtube.com/@go-cose-community3000) + +Participation in the go-cose community is governed by the Veraison [CODE_OF_CONDUCT.md](https://github.com/veraison/.github/blob/main/CODE_OF_CONDUCT.md) and [GOVERNANCE.md](https://github.com/veraison/community/blob/main/GOVERNANCE.md) + +## Code of Conduct + +This project has adopted the [Contributor Covenant Code of Conduct](https://github.com/veraison/.github/blob/main/CODE_OF_CONDUCT.md). + ## Installation go-cose is compatible with modern Go releases in module mode, with Go installed: @@ -46,7 +65,7 @@ go get github.com/veraison/go-cose@main import "github.com/veraison/go-cose" ``` -Construct a new COSE_Sign1 message, then sign it using ECDSA w/ SHA-256 and finally marshal it. For example: +Construct a new COSE_Sign1_Tagged message, then sign it using ECDSA w/ SHA-256 and finally marshal it. For example: ```go package main @@ -83,7 +102,7 @@ func SignP256(data []byte) ([]byte, error) { } ``` -Verify a raw COSE_Sign1 message. For example: +Verify a raw COSE_Sign1_Tagged message. For example: ```go package main @@ -113,6 +132,11 @@ func VerifyP256(publicKey crypto.PublicKey, sig []byte) error { See [example_test.go](./example_test.go) for more examples. +#### Untagged Signing and Verification + +Untagged COSE_Sign1 messages can be signed and verified as above, using +`cose.UntaggedSign1Message` instead of `cose.Sign1Message`. + ### About hashing `go-cose` does not import any hash package by its own to avoid linking unnecessary algorithms to the final binary. @@ -188,4 +212,4 @@ go test -fuzz=FuzzSign1 [mozilla-contributors]: https://github.com/mozilla-services/go-cose/graphs/contributors [mozilla-go-cose]: http://github.com/mozilla-services/go-cose [veraison-go-cose]: https://github.com/veraison/go-cose -[release-rc-1]: https://github.com/veraison/go-cose/releases/tag/v1.0.0-rc.1 +[current-release]: https://github.com/veraison/go-cose/releases/tag/v1.0.0 diff --git a/vendor/github.com/veraison/go-cose/SECURITY.md b/vendor/github.com/veraison/go-cose/SECURITY.md index a11239e2bd..d4ab969dd7 100644 --- a/vendor/github.com/veraison/go-cose/SECURITY.md +++ b/vendor/github.com/veraison/go-cose/SECURITY.md @@ -4,11 +4,11 @@ This document provides the details on the veraison/go-cose security policy and d ## Supported Versions -[go-cose][go-cose] is currently is in active development, moving to a [1.0.0 release][v1.0.0-milestone]. The latest pre-release will be supported until 1.0.0 is released. As 1.0.0 is released, pre-release references will need to be redirected to 1.0.0. +The current stable release of [go-cose][go-cose] is [v1.0.0][v1.0.0-release]. Please upgrade to [v1.0.0][v1.0.0-release] if you are using a pre-release version. | Version | Supported | | ------- | ------------------ | -| [v1.0.0-rc1][v1.0.0-rc1-release] | Yes | +| [v1.0.0][v1.0.0-release] | Yes | ## Report A Vulnerability @@ -23,7 +23,7 @@ To make a report please email the private security list at = 24 { + return data, nil + } + case 25: + if data[1] != 0 { + return data, nil + } + case 26: + if data[1] != 0 || data[2] != 0 { + return data, nil + } + case 27: + if data[1] != 0 || data[2] != 0 || data[3] != 0 || data[4] != 0 { + return data, nil + } + } + + // slow path: convert by re-encoding + // error checking is not required since `data` has been validataed + var s []byte + _ = decModeWithTagsForbidden.Unmarshal(data, &s) + return encMode.Marshal(s) +} diff --git a/vendor/github.com/veraison/go-cose/errors.go b/vendor/github.com/veraison/go-cose/errors.go index e0ef4ef89a..8c240e2854 100644 --- a/vendor/github.com/veraison/go-cose/errors.go +++ b/vendor/github.com/veraison/go-cose/errors.go @@ -13,4 +13,5 @@ var ( ErrNoSignatures = errors.New("no signatures attached") ErrUnavailableHashFunc = errors.New("hash function is not available") ErrVerification = errors.New("verification error") + ErrInvalidPubKey = errors.New("invalid public key") ) diff --git a/vendor/github.com/veraison/go-cose/sign.go b/vendor/github.com/veraison/go-cose/sign.go index 54d9ef2efd..cd86d11869 100644 --- a/vendor/github.com/veraison/go-cose/sign.go +++ b/vendor/github.com/veraison/go-cose/sign.go @@ -220,8 +220,16 @@ func (s *Signature) toBeSigned(bodyProtected cbor.RawMessage, payload, external // external_aad : bstr, // payload : bstr // ] + bodyProtected, err := deterministicBinaryString(bodyProtected) + if err != nil { + return nil, err + } var signProtected cbor.RawMessage - signProtected, err := s.Headers.MarshalProtected() + signProtected, err = s.Headers.MarshalProtected() + if err != nil { + return nil, err + } + signProtected, err = deterministicBinaryString(signProtected) if err != nil { return nil, err } diff --git a/vendor/github.com/veraison/go-cose/sign1.go b/vendor/github.com/veraison/go-cose/sign1.go index 3b2d111805..fa229e99f7 100644 --- a/vendor/github.com/veraison/go-cose/sign1.go +++ b/vendor/github.com/veraison/go-cose/sign1.go @@ -52,22 +52,11 @@ func NewSign1Message() *Sign1Message { // MarshalCBOR encodes Sign1Message into a COSE_Sign1_Tagged object. func (m *Sign1Message) MarshalCBOR() ([]byte, error) { - if m == nil { - return nil, errors.New("cbor: MarshalCBOR on nil Sign1Message pointer") - } - if len(m.Signature) == 0 { - return nil, ErrEmptySignature - } - protected, unprotected, err := m.Headers.marshal() + content, err := m.getContent() if err != nil { return nil, err } - content := sign1Message{ - Protected: protected, - Unprotected: unprotected, - Payload: m.Payload, - Signature: m.Signature, - } + return encMode.Marshal(cbor.Tag{ Number: CBORTagSign1Message, Content: content, @@ -85,28 +74,7 @@ func (m *Sign1Message) UnmarshalCBOR(data []byte) error { return errors.New("cbor: invalid COSE_Sign1_Tagged object") } - // decode to sign1Message and parse - var raw sign1Message - if err := decModeWithTagsForbidden.Unmarshal(data[1:], &raw); err != nil { - return err - } - if len(raw.Signature) == 0 { - return ErrEmptySignature - } - msg := Sign1Message{ - Headers: Headers{ - RawProtected: raw.Protected, - RawUnprotected: raw.Unprotected, - }, - Payload: raw.Payload, - Signature: raw.Signature, - } - if err := msg.Headers.UnmarshalFromRaw(); err != nil { - return err - } - - *m = msg - return nil + return m.doUnmarshal(data[1:]) } // Sign signs a Sign1Message using the provided Signer. @@ -199,6 +167,10 @@ func (m *Sign1Message) toBeSigned(external []byte) ([]byte, error) { if err != nil { return nil, err } + protected, err = deterministicBinaryString(protected) + if err != nil { + return nil, err + } if external == nil { external = []byte{} } @@ -214,6 +186,53 @@ func (m *Sign1Message) toBeSigned(external []byte) ([]byte, error) { return encMode.Marshal(sigStructure) } +func (m *Sign1Message) getContent() (sign1Message, error) { + if m == nil { + return sign1Message{}, errors.New("cbor: MarshalCBOR on nil Sign1Message pointer") + } + if len(m.Signature) == 0 { + return sign1Message{}, ErrEmptySignature + } + protected, unprotected, err := m.Headers.marshal() + if err != nil { + return sign1Message{}, err + } + + content := sign1Message{ + Protected: protected, + Unprotected: unprotected, + Payload: m.Payload, + Signature: m.Signature, + } + + return content, nil +} + +func (m *Sign1Message) doUnmarshal(data []byte) error { + // decode to sign1Message and parse + var raw sign1Message + if err := decModeWithTagsForbidden.Unmarshal(data, &raw); err != nil { + return err + } + if len(raw.Signature) == 0 { + return ErrEmptySignature + } + msg := Sign1Message{ + Headers: Headers{ + RawProtected: raw.Protected, + RawUnprotected: raw.Unprotected, + }, + Payload: raw.Payload, + Signature: raw.Signature, + } + if err := msg.Headers.UnmarshalFromRaw(); err != nil { + return err + } + + *m = msg + return nil +} + // Sign1 signs a Sign1Message using the provided Signer. // // This method is a wrapper of `Sign1Message.Sign()`. @@ -230,3 +249,71 @@ func Sign1(rand io.Reader, signer Signer, headers Headers, payload []byte, exter } return msg.MarshalCBOR() } + +type UntaggedSign1Message Sign1Message + +// MarshalCBOR encodes UntaggedSign1Message into a COSE_Sign1 object. +func (m *UntaggedSign1Message) MarshalCBOR() ([]byte, error) { + content, err := (*Sign1Message)(m).getContent() + if err != nil { + return nil, err + } + + return encMode.Marshal(content) +} + +// UnmarshalCBOR decodes a COSE_Sign1 object into an UnataggedSign1Message. +func (m *UntaggedSign1Message) UnmarshalCBOR(data []byte) error { + if m == nil { + return errors.New("cbor: UnmarshalCBOR on nil UntaggedSign1Message pointer") + } + + if len(data) == 0 { + return errors.New("cbor: zero length data") + } + + // fast message check - ensure the frist byte indicates a four-element array + if data[0] != sign1MessagePrefix[1] { + return errors.New("cbor: invalid COSE_Sign1 object") + } + + return (*Sign1Message)(m).doUnmarshal(data) +} + +// Sign signs an UnttaggedSign1Message using the provided Signer. +// The signature is stored in m.Signature. +// +// Note that m.Signature is only valid as long as m.Headers.Protected and +// m.Payload remain unchanged after calling this method. +// It is possible to modify m.Headers.Unprotected after signing, +// i.e., add counter signatures or timestamps. +// +// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4 +func (m *UntaggedSign1Message) Sign(rand io.Reader, external []byte, signer Signer) error { + return (*Sign1Message)(m).Sign(rand, external, signer) +} + +// Verify verifies the signature on the UntaggedSign1Message returning nil on success or +// a suitable error if verification fails. +// +// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4 +func (m *UntaggedSign1Message) Verify(external []byte, verifier Verifier) error { + return (*Sign1Message)(m).Verify(external, verifier) +} + +// Sign1Untagged signs an UntaggedSign1Message using the provided Signer. +// +// This method is a wrapper of `UntaggedSign1Message.Sign()`. +// +// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4 +func Sign1Untagged(rand io.Reader, signer Signer, headers Headers, payload []byte, external []byte) ([]byte, error) { + msg := UntaggedSign1Message{ + Headers: headers, + Payload: payload, + } + err := msg.Sign(rand, external, signer) + if err != nil { + return nil, err + } + return msg.MarshalCBOR() +} diff --git a/vendor/github.com/veraison/go-cose/signer.go b/vendor/github.com/veraison/go-cose/signer.go index bac4224ae8..674754670e 100644 --- a/vendor/github.com/veraison/go-cose/signer.go +++ b/vendor/github.com/veraison/go-cose/signer.go @@ -41,7 +41,7 @@ func NewSigner(alg Algorithm, key crypto.Signer) (Signer, error) { case AlgorithmPS256, AlgorithmPS384, AlgorithmPS512: vk, ok := key.Public().(*rsa.PublicKey) if !ok { - return nil, fmt.Errorf("%v: %w", alg, ErrAlgorithmMismatch) + return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey) } // RFC 8230 6.1 requires RSA keys having a minimum size of 2048 bits. // Reference: https://www.rfc-editor.org/rfc/rfc8230.html#section-6.1 @@ -55,7 +55,7 @@ func NewSigner(alg Algorithm, key crypto.Signer) (Signer, error) { case AlgorithmES256, AlgorithmES384, AlgorithmES512: vk, ok := key.Public().(*ecdsa.PublicKey) if !ok { - return nil, fmt.Errorf("%v: %w", alg, ErrAlgorithmMismatch) + return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey) } if sk, ok := key.(*ecdsa.PrivateKey); ok { return &ecdsaKeySigner{ @@ -70,7 +70,7 @@ func NewSigner(alg Algorithm, key crypto.Signer) (Signer, error) { }, nil case AlgorithmEd25519: if _, ok := key.Public().(ed25519.PublicKey); !ok { - return nil, fmt.Errorf("%v: %w", alg, ErrAlgorithmMismatch) + return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey) } return &ed25519Signer{ key: key, diff --git a/vendor/github.com/veraison/go-cose/verifier.go b/vendor/github.com/veraison/go-cose/verifier.go index 266e6d9877..1c6e83b457 100644 --- a/vendor/github.com/veraison/go-cose/verifier.go +++ b/vendor/github.com/veraison/go-cose/verifier.go @@ -30,7 +30,7 @@ func NewVerifier(alg Algorithm, key crypto.PublicKey) (Verifier, error) { case AlgorithmPS256, AlgorithmPS384, AlgorithmPS512: vk, ok := key.(*rsa.PublicKey) if !ok { - return nil, fmt.Errorf("%v: %w", alg, ErrAlgorithmMismatch) + return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey) } // RFC 8230 6.1 requires RSA keys having a minimun size of 2048 bits. // Reference: https://www.rfc-editor.org/rfc/rfc8230.html#section-6.1 @@ -44,7 +44,7 @@ func NewVerifier(alg Algorithm, key crypto.PublicKey) (Verifier, error) { case AlgorithmES256, AlgorithmES384, AlgorithmES512: vk, ok := key.(*ecdsa.PublicKey) if !ok { - return nil, fmt.Errorf("%v: %w", alg, ErrAlgorithmMismatch) + return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey) } if !vk.Curve.IsOnCurve(vk.X, vk.Y) { return nil, errors.New("public key point is not on curve") @@ -56,7 +56,7 @@ func NewVerifier(alg Algorithm, key crypto.PublicKey) (Verifier, error) { case AlgorithmEd25519: vk, ok := key.(ed25519.PublicKey) if !ok { - return nil, fmt.Errorf("%v: %w", alg, ErrAlgorithmMismatch) + return nil, fmt.Errorf("%v: %w", alg, ErrInvalidPubKey) } return &ed25519Verifier{ key: vk, diff --git a/vendor/modules.txt b/vendor/modules.txt index fe2efe7a1b..29520cc3e0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -388,7 +388,7 @@ github.com/vektah/gqlparser/v2/lexer github.com/vektah/gqlparser/v2/parser github.com/vektah/gqlparser/v2/validator github.com/vektah/gqlparser/v2/validator/rules -# github.com/veraison/go-cose v1.0.0 +# github.com/veraison/go-cose v1.1.0 ## explicit; go 1.18 github.com/veraison/go-cose # github.com/vishvananda/netlink v1.2.1-beta.2