Skip to content

Commit

Permalink
update: enabled cose to verify time in Tag1 Datetime format (#95)
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Zheng <patrickzheng@microsoft.com>
  • Loading branch information
Two-Hearts authored Nov 23, 2022
1 parent cd56ef6 commit 9b5de08
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 28 deletions.
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ module github.com/notaryproject/notation-core-go
go 1.18

require (
github.com/fxamacker/cbor/v2 v2.4.0
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/veraison/go-cose v1.0.0-rc.2
)

require (
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
)
require github.com/x448/float16 v0.8.4 // indirect
8 changes: 3 additions & 5 deletions signature/cose/conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import (
)

type sign1 struct {
SigningTime int64 `json:"signingTime"`
Expiry int64 `json:"expiry"`
Payload string `json:"payload"`
ProtectedHeaders *cborStruct `json:"protectedHeaders"`
UnprotectedHeaders *cborStruct `json:"unprotectedHeaders"`
Expand Down Expand Up @@ -125,8 +123,8 @@ func getSignReq(sign1 *sign1) (*signature.SignRequest, error) {
Content: []byte("hello COSE"),
},
Signer: signer,
SigningTime: time.Unix(sign1.SigningTime, 0),
Expiry: time.Unix(sign1.Expiry, 0),
SigningTime: time.Unix(1661321924, 0),
Expiry: time.Unix(1661408324, 0),
ExtendedSignedAttributes: []signature.Attribute{
{Key: "signedCritKey1", Value: "signedCritValue1", Critical: true},
{Key: "signedKey1", Value: "signedValue1", Critical: false},
Expand Down Expand Up @@ -195,7 +193,7 @@ func generateSign1(msg *cose.Sign1Message) *cose.Sign1Message {
newMsg.Headers.Protected = msg.Headers.Protected
newMsg.Headers.Unprotected["io.cncf.notary.signingAgent"] = msg.Headers.Unprotected["io.cncf.notary.signingAgent"]
newMsg.Payload = msg.Payload
newMsg.Signature = hexToBytes("31b6cb0cd9c974b39d603465811c2aa3d96a5dff89f80b33cb4e321dc6e68a29b4ba65c00f0f9f22ee4376abfaec2cba6fd21c6881ecaab25775e3fb9226a88cf41660b2d6fd14184540d07ded3744e19ff9dbdd081e15c8f77bb6ca3072ef57141594fad4ea57d206c6b8dd3a6e0a0a7ed764ff08dbcc439bd722e1b3d282921a579a3d860cceea37d633184f9316cb6b4fa4ea550da5ad9e5bf3c2d768a787da76e594290cb10b5b1ead8b7e75967de28e9ff429fe9db814380608a15674f9741563902a620f312213d9dce5c264017cbcb3bb4f8cebee0d5ef32b364f68c11cba5630fac8e3165d06fdebaca095267223c552fe605b4529f25b65f8fa47b010b9096cec275307e82b1062f660a73e07d0b85b978b4a59b5cde51fc9a031b488a3deb38fc312a64ef2ec1250238ae16cfefc00d9aa1ceb938fe6de51f265eebe975c29f4cff8ab0afb40c45e8c985d17347bf20f455851c1a46ab655f51a159cf8910a424c5a8bbdd239e49e43a73c7b5174de29e835063e5e64b459558de5")
newMsg.Signature = hexToBytes("5bfec0a345098b9b9b6fb7358face7ab76d191b648ccd19e36fb03c2085ea072ec050d9c6e4fa4845478386d0831a2360d343a1ff027bdd56d496f996b90ac2db9da2460baffec21db7c0ca759ba83ab35cdf521c0926138681bde05277e2976cedbeb4040c930908ef2b113d935378bd3c5e7740119b2b81c59e9c6c24411abdf699547864f68f2e0f6346eeff627bf0d971abdf94e67e12a10134ccbbadfa0ab4031b18705696a9567a0f1f061247fdd00d343ea3a45f63da7f80771612b38fc9877375bcbce28aef1f3ee2b25869722c24737c49d8c6711376dd62b3d32b24d489746e2ba5d25fa76febcc6abf9d2baee67221c85a7a8f8763dadc5e20bb8c5c03a75c68211557813d2d6adea56ec5526f78c18460b1944c8307a4b0ed64a6d6b4abed5067de5a5ad38948a2ea140b01a7762c15b3e63d7d7bdc8962e6c4bff18b34d2a19fc627f02ebf88daf7fb25c55ce1b9ca06ade02f9d60ad16cb306f433f692e598132d67b5d0a02193191d5c9cd52ad81f4e31917e5b5d40ef5ce7")
return newMsg
}

Expand Down
103 changes: 91 additions & 12 deletions signature/cose/envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"crypto"
"crypto/rand"
"crypto/x509"
"errors"
"fmt"
"io"
"strconv"
"time"

"github.com/fxamacker/cbor/v2"
"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation-core-go/signature/internal/base"
"github.com/veraison/go-cose"
Expand All @@ -17,10 +19,37 @@ import (
// MediaTypeEnvelope is the COSE signature envelope blob mediaType.
const MediaTypeEnvelope = "application/cose"

var (
// encMode is the encoding mode used in Sign
encMode cbor.EncMode

// decMode is the decoding mode used in Content
decMode cbor.DecMode
)

func init() {
if err := signature.RegisterEnvelopeType(MediaTypeEnvelope, NewEnvelope, ParseEnvelope); err != nil {
err := signature.RegisterEnvelopeType(MediaTypeEnvelope, NewEnvelope, ParseEnvelope)
if err != nil {
panic(err)
}

encOpts := cbor.EncOptions{
Time: cbor.TimeUnix,
TimeTag: cbor.EncTagRequired,
}
encMode, err = encOpts.EncMode()
if err != nil {
panic(err)
}

decOpts := cbor.DecOptions{
TimeTag: cbor.DecTagRequired,
}
decMode, err = decOpts.DecMode()
if err != nil {
panic(err)
}

}

// Protected Headers
Expand Down Expand Up @@ -204,6 +233,7 @@ func (e *envelope) Sign(req *signature.SignRequest) ([]byte, error) {
return nil, &signature.InvalidSignatureError{Msg: err.Error()}
}
e.base = msg

return encoded, nil
}

Expand Down Expand Up @@ -393,15 +423,23 @@ func generateProtectedHeaders(req *signature.SignRequest, protected cose.Protect
if !ok {
return &signature.InvalidSignRequestError{Msg: "signing scheme: require notary.x509 or notary.x509.signingAuthority"}
}
protected[signingTimeLabel] = req.SigningTime.Unix()
rawTimeCBOR, err := encodeTime(req.SigningTime)
if err != nil {
return &signature.InvalidSignRequestError{Msg: fmt.Sprintf("signing time: %q", err)}
}
protected[signingTimeLabel] = rawTimeCBOR
if signingTimeLabel == headerLabelAuthenticSigningTime {
crit = append(crit, headerLabelAuthenticSigningTime)
}

// expiry
if !req.Expiry.IsZero() {
crit = append(crit, headerLabelExpiry)
protected[headerLabelExpiry] = req.Expiry.Unix()
rawExpiryCBOR, err := encodeTime(req.Expiry)
if err != nil {
return &signature.InvalidSignRequestError{Msg: fmt.Sprintf("expiry: %q", err)}
}
protected[headerLabelExpiry] = rawExpiryCBOR
}

// extended attributes
Expand Down Expand Up @@ -471,19 +509,19 @@ func parseProtectedHeaders(protected cose.ProtectedHeader, signerInfo *signature
if !ok {
return &signature.InvalidSignatureError{Msg: "unsupported signingScheme: " + signingSchemeString}
}
signingTime, ok := protected[signingTimeLabel].(int64)
if !ok {
return &signature.InvalidSignatureError{Msg: "invalid signingTime under signing scheme: " + signingSchemeString}
signingTime, err := parseTime(protected[signingTimeLabel])
if err != nil {
return &signature.InvalidSignatureError{Msg: fmt.Sprintf("invalid signingTime: %v", err)}
}
signerInfo.SignedAttributes.SigningTime = time.Unix(signingTime, 0)
signerInfo.SignedAttributes.SigningTime = signingTime

// populate signerInfo.SignedAttributes.Expiry
if exp, ok := protected[headerLabelExpiry]; ok {
expiry, ok := exp.(int64)
if !ok {
return &signature.InvalidSignatureError{Msg: "expiry requires int64 type"}
if _, ok := protected[headerLabelExpiry]; ok {
expiry, err := parseTime(protected[headerLabelExpiry])
if err != nil {
return &signature.InvalidSignatureError{Msg: fmt.Sprintf("invalid expiry: %v", err)}
}
signerInfo.SignedAttributes.Expiry = time.Unix(expiry, 0)
signerInfo.SignedAttributes.Expiry = expiry
}

// populate signerInfo.SignedAttributes.ExtendedAttributes
Expand Down Expand Up @@ -569,3 +607,44 @@ func contains(s []interface{}, e interface{}) bool {
}
return false
}

// encodeTime generates a Tag1 Datetime CBOR object and casts it to
// cbor.RawMessage
func encodeTime(t time.Time) (cbor.RawMessage, error) {
timeCBOR, err := encMode.Marshal(t)
if err != nil {
return nil, err
}

return cbor.RawMessage(timeCBOR), nil
}

// decodeTime decodes cbor.RawMessage of Tag1 Datetime CBOR object
// into time.Time
func decodeTime(timeRaw cbor.RawMessage) (time.Time, error) {
var t time.Time
err := decMode.Unmarshal([]byte(timeRaw), &t)
if err != nil {
return time.Time{}, err
}

return t, nil
}

// parseTime parses time values from cose.ProtectedHeader
// in go-cose, CBOR times (tag 1) decode to time.Time.
//
// For more details: https://github.com/fxamacker/cbor/blob/7704fa5efaf3ef4ac35aff38f50f6ff567793072/decode.go#L52
func parseTime(timeValue interface{}) (time.Time, error) {
switch t := timeValue.(type) {
case cbor.RawMessage:
return decodeTime(t)
// TODO: need a way to check the tag number of datetime inside the signature
// and fail if it's a Tag0. We only accept Tag1 datetime.
// https://github.com/notaryproject/notation-core-go/issues/97
case time.Time:
return t, nil
}

return time.Time{}, errors.New("invalid timeValue type")
}
20 changes: 18 additions & 2 deletions signature/cose/envelope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"
"time"

"github.com/fxamacker/cbor/v2"
"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation-core-go/signature/signaturetest"
"github.com/notaryproject/notation-core-go/testhelper"
Expand Down Expand Up @@ -538,14 +539,29 @@ func TestSignerInfoErrors(t *testing.T) {
}
})

t.Run("when decodeTime fails", func(t *testing.T) {
env, err := getVerifyCOSE("notary.x509", signature.KeyTypeRSA, 3072)
if err != nil {
t.Fatalf("getVerifyCOSE() failed. Error = %s", err)
}
raw := cbor.RawMessage{}
env.base.Headers.Protected[headerLabelSigningTime] = raw
raw = nil
_, err = env.Content()
expected := errors.New("invalid signingTime: EOF")
if !isErrEqual(expected, err) {
t.Fatalf("Content() expects error: %v, but got: %v.", expected, err)
}
})

t.Run("when COSE envelope protected header has invalid signingTime", func(t *testing.T) {
env, err := getVerifyCOSE("notary.x509", signature.KeyTypeRSA, 3072)
if err != nil {
t.Fatalf("getVerifyCOSE() failed. Error = %s", err)
}
env.base.Headers.Protected[headerLabelSigningTime] = "invalid"
_, err = env.Content()
expected := errors.New("invalid signingTime under signing scheme: notary.x509")
expected := errors.New("invalid signingTime: invalid timeValue type")
if !isErrEqual(expected, err) {
t.Fatalf("Content() expects error: %v, but got: %v.", expected, err)
}
Expand All @@ -558,7 +574,7 @@ func TestSignerInfoErrors(t *testing.T) {
}
env.base.Headers.Protected[headerLabelExpiry] = "invalid"
_, err = env.Content()
expected := errors.New("expiry requires int64 type")
expected := errors.New("invalid expiry: invalid timeValue type")
if !isErrEqual(expected, err) {
t.Fatalf("Content() expects error: %v, but got: %v.", expected, err)
}
Expand Down
8 changes: 4 additions & 4 deletions signature/cose/testdata/conformance.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"expiry": 1661408324,
"payload": "68656C6C6F20434F5345",
"protectedHeaders": {
"cborHex": "A80138250283781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D6575696F2E636E63662E6E6F746172792E6578706972796E7369676E6564437269744B65793103782B6170706C69636174696F6E2F766E642E636E63662E6E6F746172792E7061796C6F61642E76312B6A736F6E6A7369676E65644B6579316C7369676E656456616C7565316E7369676E6564437269744B657931707369676E65644372697456616C75653175696F2E636E63662E6E6F746172792E6578706972791A63071444781A696F2E636E63662E6E6F746172792E7369676E696E6754696D651A6305C2C4781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D656B6E6F746172792E78353039",
"cborDiag": "{1: -38, 2: [\"io.cncf.notary.signingScheme\", \"io.cncf.notary.expiry\", \"signedCritKey1\"], 3: \"application/vnd.cncf.notary.payload.v1+json\", \"signedKey1\": \"signedValue1\", \"signedCritKey1\": \"signedCritValue1\", \"io.cncf.notary.expiry\": 1661408324, \"io.cncf.notary.signingTime\": 1661321924, \"io.cncf.notary.signingScheme\": \"notary.x509\"}"
"cborHex": "A80138250283781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D6575696F2E636E63662E6E6F746172792E6578706972796E7369676E6564437269744B65793103782B6170706C69636174696F6E2F766E642E636E63662E6E6F746172792E7061796C6F61642E76312B6A736F6E6A7369676E65644B6579316C7369676E656456616C7565316E7369676E6564437269744B657931707369676E65644372697456616C75653175696F2E636E63662E6E6F746172792E657870697279C11A63071444781A696F2E636E63662E6E6F746172792E7369676E696E6754696D65C11A6305C2C4781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D656B6E6F746172792E78353039",
"cborDiag": "{1: -38, 2: [\"io.cncf.notary.signingScheme\", \"io.cncf.notary.expiry\", \"signedCritKey1\"], 3: \"application/vnd.cncf.notary.payload.v1+json\", \"signedKey1\": \"signedValue1\", \"signedCritKey1\": \"signedCritValue1\", \"io.cncf.notary.expiry\": 1(1661408324), \"io.cncf.notary.signingTime\": 1(1661321924), \"io.cncf.notary.signingScheme\": \"notary.x509\"}"
},
"unprotectedHeaders": {
"cborHex": "A1781B696F2E636E63662E6E6F746172792E7369676E696E674167656E74781D4E6F746174696F6E436F6E666F726D616E6365546573742F312E302E30",
"cborDiag": "{\"io.cncf.notary.signingAgent\":\"NotationConformanceTest/1.0.0\"}"
},
"expectedOutput": {
"cborHex": "D284590115A80138250283781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D6575696F2E636E63662E6E6F746172792E6578706972796E7369676E6564437269744B65793103782B6170706C69636174696F6E2F766E642E636E63662E6E6F746172792E7061796C6F61642E76312B6A736F6E6A7369676E65644B6579316C7369676E656456616C7565316E7369676E6564437269744B657931707369676E65644372697456616C75653175696F2E636E63662E6E6F746172792E6578706972791A63071444781A696F2E636E63662E6E6F746172792E7369676E696E6754696D651A6305C2C4781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D656B6E6F746172792E78353039A1781B696F2E636E63662E6E6F746172792E7369676E696E674167656E74781D4E6F746174696F6E436F6E666F726D616E6365546573742F312E302E304A68656C6C6F20434F534559018031B6CB0CD9C974B39D603465811C2AA3D96A5DFF89F80B33CB4E321DC6E68A29B4BA65C00F0F9F22EE4376ABFAEC2CBA6FD21C6881ECAAB25775E3FB9226A88CF41660B2D6FD14184540D07DED3744E19FF9DBDD081E15C8F77BB6CA3072EF57141594FAD4EA57D206C6B8DD3A6E0A0A7ED764FF08DBCC439BD722E1B3D282921A579A3D860CCEEA37D633184F9316CB6B4FA4EA550DA5AD9E5BF3C2D768A787DA76E594290CB10B5B1EAD8B7E75967DE28E9FF429FE9DB814380608A15674F9741563902A620F312213D9DCE5C264017CBCB3BB4F8CEBEE0D5EF32B364F68C11CBA5630FAC8E3165D06FDEBACA095267223C552FE605B4529F25B65F8FA47B010B9096CEC275307E82B1062F660A73E07D0B85B978B4A59B5CDE51FC9A031B488A3DEB38FC312A64EF2EC1250238AE16CFEFC00D9AA1CEB938FE6DE51F265EEBE975C29F4CFF8AB0AFB40C45E8C985D17347BF20F455851C1A46AB655F51A159CF8910A424C5A8BBDD239E49E43A73C7B5174DE29E835063E5E64B459558DE5",
"cborDiag": "18([h'A80138250283781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D6575696F2E636E63662E6E6F746172792E6578706972796E7369676E6564437269744B65793103782B6170706C69636174696F6E2F766E642E636E63662E6E6F746172792E7061796C6F61642E76312B6A736F6E6A7369676E65644B6579316C7369676E656456616C7565316E7369676E6564437269744B657931707369676E65644372697456616C75653175696F2E636E63662E6E6F746172792E6578706972791A63071444781A696F2E636E63662E6E6F746172792E7369676E696E6754696D651A6305C2C4781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D656B6E6F746172792E78353039', {\"io.cncf.notary.signingAgent\":\"NotationConformanceTest/1.0.0\"}, h'68656C6C6F20434F5345', h'31b6cb0cd9c974b39d603465811c2aa3d96a5dff89f80b33cb4e321dc6e68a29b4ba65c00f0f9f22ee4376abfaec2cba6fd21c6881ecaab25775e3fb9226a88cf41660b2d6fd14184540d07ded3744e19ff9dbdd081e15c8f77bb6ca3072ef57141594fad4ea57d206c6b8dd3a6e0a0a7ed764ff08dbcc439bd722e1b3d282921a579a3d860cceea37d633184f9316cb6b4fa4ea550da5ad9e5bf3c2d768a787da76e594290cb10b5b1ead8b7e75967de28e9ff429fe9db814380608a15674f9741563902a620f312213d9dce5c264017cbcb3bb4f8cebee0d5ef32b364f68c11cba5630fac8e3165d06fdebaca095267223c552fe605b4529f25b65f8fa47b010b9096cec275307e82b1062f660a73e07d0b85b978b4a59b5cde51fc9a031b488a3deb38fc312a64ef2ec1250238ae16cfefc00d9aa1ceb938fe6de51f265eebe975c29f4cff8ab0afb40c45e8c985d17347bf20f455851c1a46ab655f51a159cf8910a424c5a8bbdd239e49e43a73c7b5174de29e835063e5e64b459558de5'])"
"cborHex": "D284590117A80138250283781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D6575696F2E636E63662E6E6F746172792E6578706972796E7369676E6564437269744B65793103782B6170706C69636174696F6E2F766E642E636E63662E6E6F746172792E7061796C6F61642E76312B6A736F6E6A7369676E65644B6579316C7369676E656456616C7565316E7369676E6564437269744B657931707369676E65644372697456616C75653175696F2E636E63662E6E6F746172792E657870697279C11A63071444781A696F2E636E63662E6E6F746172792E7369676E696E6754696D65C11A6305C2C4781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D656B6E6F746172792E78353039A1781B696F2E636E63662E6E6F746172792E7369676E696E674167656E74781D4E6F746174696F6E436F6E666F726D616E6365546573742F312E302E304A68656C6C6F20434F53455901805BFEC0A345098B9B9B6FB7358FACE7AB76D191B648CCD19E36FB03C2085EA072EC050D9C6E4FA4845478386D0831A2360D343A1FF027BDD56D496F996B90AC2DB9DA2460BAFFEC21DB7C0CA759BA83AB35CDF521C0926138681BDE05277E2976CEDBEB4040C930908EF2B113D935378BD3C5E7740119B2B81C59E9C6C24411ABDF699547864F68F2E0F6346EEFF627BF0D971ABDF94E67E12A10134CCBBADFA0AB4031B18705696A9567A0F1F061247FDD00D343EA3A45F63DA7F80771612B38FC9877375BCBCE28AEF1F3EE2B25869722C24737C49D8C6711376DD62B3D32B24D489746E2BA5D25FA76FEBCC6ABF9D2BAEE67221C85A7A8F8763DADC5E20BB8C5C03A75C68211557813D2D6ADEA56EC5526F78C18460B1944C8307A4B0ED64A6D6B4ABED5067DE5A5AD38948A2EA140B01A7762C15B3E63D7D7BDC8962E6C4BFF18B34D2A19FC627F02EBF88DAF7FB25C55CE1B9CA06ADE02F9D60AD16CB306F433F692E598132D67B5D0A02193191D5C9CD52AD81F4E31917E5B5D40EF5CE7",
"cborDiag": "18([h'A80138250283781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D6575696F2E636E63662E6E6F746172792E6578706972796E7369676E6564437269744B65793103782B6170706C69636174696F6E2F766E642E636E63662E6E6F746172792E7061796C6F61642E76312B6A736F6E6A7369676E65644B6579316C7369676E656456616C7565316E7369676E6564437269744B657931707369676E65644372697456616C75653175696F2E636E63662E6E6F746172792E657870697279C11A63071444781A696F2E636E63662E6E6F746172792E7369676E696E6754696D65C11A6305C2C4781C696F2E636E63662E6E6F746172792E7369676E696E67536368656D656B6E6F746172792E78353039', {\"io.cncf.notary.signingAgent\":\"NotationConformanceTest/1.0.0\"}, h'68656C6C6F20434F5345', h'5bfec0a345098b9b9b6fb7358face7ab76d191b648ccd19e36fb03c2085ea072ec050d9c6e4fa4845478386d0831a2360d343a1ff027bdd56d496f996b90ac2db9da2460baffec21db7c0ca759ba83ab35cdf521c0926138681bde05277e2976cedbeb4040c930908ef2b113d935378bd3c5e7740119b2b81c59e9c6c24411abdf699547864f68f2e0f6346eeff627bf0d971abdf94e67e12a10134ccbbadfa0ab4031b18705696a9567a0f1f061247fdd00d343ea3a45f63da7f80771612b38fc9877375bcbce28aef1f3ee2b25869722c24737c49d8c6711376dd62b3d32b24d489746e2ba5d25fa76febcc6abf9d2baee67221c85a7a8f8763dadc5e20bb8c5c03a75c68211557813d2d6adea56ec5526f78c18460b1944c8307a4b0ed64a6d6b4abed5067de5a5ad38948a2ea140b01a7762c15b3e63d7d7bdc8962e6c4bff18b34d2a19fc627f02ebf88daf7fb25c55ce1b9ca06ade02f9d60ad16cb306f433f692e598132d67b5d0a02193191d5c9cd52ad81f4e31917e5b5d40ef5ce7'])"
}
}
2 changes: 1 addition & 1 deletion signature/internal/base/envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func validateSignRequest(req *signature.SignRequest) error {
if _, err := req.Signer.KeySpec(); err != nil {
return err
}

return validateSigningSchema(req.SigningScheme)
}

Expand Down

0 comments on commit 9b5de08

Please sign in to comment.