From db53e2ea39ab6ab7c2a6d0a5980a018a40e0aa6b Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Thu, 18 Jun 2020 15:47:55 +0300 Subject: [PATCH 1/2] service: make RequestData to provide ExtendedHeadersSource interface --- service/meta.go | 45 +++++++++++++++++++++++++++++++++++++++++++ service/meta_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++ service/sign_test.go | 6 ++++++ service/types.go | 1 + 4 files changed, 98 insertions(+) diff --git a/service/meta.go b/service/meta.go index e838cec..557d076 100644 --- a/service/meta.go +++ b/service/meta.go @@ -4,6 +4,10 @@ import ( "io" ) +type extHdrWrapper struct { + msg *RequestExtendedHeader_KV +} + type extHdrSrcWrapper struct { extHdrSrc ExtendedHeadersSource } @@ -84,3 +88,44 @@ func (m *RequestExtendedHeader_KV) SetV(v string) { func (m *RequestExtendedHeader) SetHeaders(v []RequestExtendedHeader_KV) { m.Headers = v } + +func wrapExtendedHeaderKV(msg *RequestExtendedHeader_KV) extHdrWrapper { + return extHdrWrapper{ + msg: msg, + } +} + +// Key returns the result of K field getter. +// +// If message is nil, empty string returns. +func (m extHdrWrapper) Key() string { + if m.msg != nil { + return m.msg.GetK() + } + + return "" +} + +// Value returns the result of V field getter. +// +// If message is nil, empty string returns. +func (m extHdrWrapper) Value() string { + if m.msg != nil { + return m.msg.GetV() + } + + return "" +} + +// ExtendedHeaders composes ExtendedHeader list from the Headers field getter result. +func (m RequestExtendedHeader) ExtendedHeaders() []ExtendedHeader { + hs := m.GetHeaders() + + res := make([]ExtendedHeader, 0, len(hs)) + + for i := range hs { + res = append(res, wrapExtendedHeaderKV(&hs[i])) + } + + return res +} diff --git a/service/meta_test.go b/service/meta_test.go index 7c3853a..9e9c012 100644 --- a/service/meta_test.go +++ b/service/meta_test.go @@ -51,3 +51,49 @@ func TestRequestExtendedHeader_SetHeaders(t *testing.T) { require.Equal(t, hdrs, s.GetHeaders()) } + +func TestExtHdrWrapper(t *testing.T) { + s := wrapExtendedHeaderKV(nil) + require.Empty(t, s.Key()) + require.Empty(t, s.Value()) + + msg := new(RequestExtendedHeader_KV) + s = wrapExtendedHeaderKV(msg) + + key := "key" + msg.SetK(key) + require.Equal(t, key, s.Key()) + + val := "val" + msg.SetV(val) + require.Equal(t, val, s.Value()) +} + +func TestRequestExtendedHeader_ExtendedHeaders(t *testing.T) { + var ( + k1, v1 = "key1", "value1" + k2, v2 = "key2", "value2" + h1 = new(RequestExtendedHeader_KV) + h2 = new(RequestExtendedHeader_KV) + ) + + h1.SetK(k1) + h1.SetV(v1) + + h2.SetK(k2) + h2.SetV(v2) + + s := new(RequestExtendedHeader) + s.SetHeaders([]RequestExtendedHeader_KV{ + *h1, *h2, + }) + + xHdrs := s.ExtendedHeaders() + require.Len(t, xHdrs, 2) + + require.Equal(t, k1, xHdrs[0].Key()) + require.Equal(t, v1, xHdrs[0].Value()) + + require.Equal(t, k2, xHdrs[1].Key()) + require.Equal(t, v2, xHdrs[1].Value()) +} diff --git a/service/sign_test.go b/service/sign_test.go index 80c0d19..023412f 100644 --- a/service/sign_test.go +++ b/service/sign_test.go @@ -20,6 +20,8 @@ type testSignedDataSrc struct { token SessionToken bearer BearerToken + + extHdrs []ExtendedHeader } type testSignedDataReader struct { @@ -60,6 +62,10 @@ func (s testSignedDataSrc) GetBearerToken() BearerToken { return s.bearer } +func (s testSignedDataSrc) ExtendedHeaders() []ExtendedHeader { + return s.extHdrs +} + func (s testSignedDataReader) SignedDataSize() int { return len(s.data) } diff --git a/service/types.go b/service/types.go index feba2e3..75a5a0a 100644 --- a/service/types.go +++ b/service/types.go @@ -255,6 +255,7 @@ type RequestData interface { SignedDataSource SessionTokenSource BearerTokenSource + ExtendedHeadersSource } // RequestSignedData is an interface of request information with signature write access. From c360b7d19cc253a233dfe2df8c434a6063c3ce29 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Thu, 18 Jun 2020 15:50:01 +0300 Subject: [PATCH 2/2] service: add ExtendedHeader list to signed payload of the requests --- service/sign.go | 2 ++ service/sign_test.go | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/service/sign.go b/service/sign.go index a0bb7e5..50453b9 100644 --- a/service/sign.go +++ b/service/sign.go @@ -212,6 +212,7 @@ func SignRequestData(key *ecdsa.PrivateKey, src RequestSignedData) error { NewSignedBearerToken( src.GetBearerToken(), ), + ExtendedHeadersSignedData(src), ) if err != nil { return err @@ -237,6 +238,7 @@ func VerifyRequestData(src RequestVerifyData) error { NewVerifiedBearerToken( src.GetBearerToken(), ), + ExtendedHeadersSignedData(src), ) if err != nil { return err diff --git a/service/sign_test.go b/service/sign_test.go index 023412f..724c068 100644 --- a/service/sign_test.go +++ b/service/sign_test.go @@ -268,7 +268,7 @@ func TestVerifySignatureWithKey(t *testing.T) { require.Error(t, VerifySignatureWithKey(&sk.PublicKey, src)) } -func TestSignVerifyDataWithSessionToken(t *testing.T) { +func TestSignVerifyRequestData(t *testing.T) { // sign with empty RequestSignedData require.EqualError(t, SignRequestData(nil, nil), @@ -288,18 +288,27 @@ func TestSignVerifyDataWithSessionToken(t *testing.T) { bearer = wrapBearerTokenMsg(new(BearerTokenMsg)) bearerEpoch = uint64(8) + + extHdrKey = "key" + extHdr = new(RequestExtendedHeader_KV) ) token.SetVerb(initVerb) bearer.SetExpirationEpoch(bearerEpoch) + extHdr.SetK(extHdrKey) + // create test data with token src := &testSignedDataSrc{ data: testData(t, 10), token: token, bearer: bearer, + + extHdrs: []ExtendedHeader{ + wrapExtendedHeaderKV(extHdr), + }, } // create test private key @@ -344,6 +353,18 @@ func TestSignVerifyDataWithSessionToken(t *testing.T) { // ascertain that verification is passed require.NoError(t, VerifyRequestData(src)) + // break the extended header + extHdr.SetK(extHdrKey + "1") + + // ascertain that verification is failed + require.Error(t, VerifyRequestData(src)) + + // restore the extended header + extHdr.SetK(extHdrKey) + + // ascertain that verification is passed + require.NoError(t, VerifyRequestData(src)) + // wrap to data reader rdr := &testSignedDataReader{ testSignedDataSrc: src,