@@ -11,7 +11,9 @@ import (
1111 "encoding/base64"
1212 "fmt"
1313 "github.com/dunglas/httpsfv"
14+ "log"
1415 "net/http"
16+ "strings"
1517 "time"
1618)
1719
@@ -46,25 +48,80 @@ func encodeBytes(raw []byte) string {
4648}
4749
4850func generateSignatureInput (message parsedMessage , fields Fields , params string ) (string , error ) {
49- mf , err := matchFields (message .components , fields )
50- if err != nil {
51- return "" , err
52- }
5351 inp := ""
54- for _ , c := range mf {
55- f , err := c .f .asSignatureInput ()
52+ for _ , c := range fields {
53+ f , err := c .asSignatureInput ()
54+ if err != nil {
55+ return "" , fmt .Errorf ("could not marshal %v" , f )
56+ }
57+ fieldValues , err := generateFieldValues (c , message )
5658 if err != nil {
57- return "" , fmt . Errorf ( "could not marshal %v" , c . f )
59+ return "" , err
5860 }
59- for _ , v := range c . v {
61+ for _ , v := range fieldValues {
6062 inp += fmt .Sprintf ("%s: %s\n " , f , v )
6163 }
6264 }
6365 inp += fmt .Sprintf ("\" %s\" : %s" , "@signature-params" , params )
64- // log.Println("inp:", "\n"+inp)
66+ log .Println ("inp:" , "\n " + inp ) // TODO!
6567 return inp , nil
6668}
6769
70+ func generateFieldValues (f field , message parsedMessage ) ([]string , error ) {
71+ if f .flagName == "" {
72+ if strings .HasPrefix (f .name , "@" ) { // derived component
73+ return []string {message .derived [f .name ]}, nil
74+ }
75+ vv , found := message .headers [f .name ] // normal header, cannot use "Values" on lowercased header name
76+ if ! found {
77+ return nil , fmt .Errorf ("header %s not found" , f .name )
78+ }
79+ return []string {foldFields (vv )}, nil
80+ }
81+ if f .name == "@query-params" && f .flagName == "name" {
82+ vals , found := message .qParams [f .flagValue ]
83+ if ! found {
84+ return nil , fmt .Errorf ("query parameter %s not found" , f .flagValue )
85+ }
86+ return vals , nil
87+ }
88+ if f .flagName == "key" { // dictionary header
89+ return message .getDictHeader (f .name , f .flagValue )
90+ }
91+ return nil , fmt .Errorf ("unrecognized field %s" , f )
92+ }
93+
94+ func (message * parsedMessage ) getDictHeader (hdr , member string ) ([]string , error ) {
95+ vals , found := message .headers [hdr ]
96+ if ! found {
97+ return nil , fmt .Errorf ("dictionary header %s not found" , hdr )
98+ }
99+ dict , err := httpsfv .UnmarshalDictionary (vals )
100+ if err != nil {
101+ return nil , fmt .Errorf ("cannot parse dictionary for %s" , hdr )
102+ }
103+ v , found := dict .Get (member )
104+ if ! found {
105+ return nil , fmt .Errorf ("cannot find member %s of dictionary %s" , member , hdr )
106+ }
107+ switch v .(type ) {
108+ case httpsfv.Item :
109+ vv , err := httpsfv .Marshal (v .(httpsfv.Item ))
110+ if err != nil {
111+ return nil , fmt .Errorf ("malformed dictionry member %s: %v" , hdr , err )
112+ }
113+ return []string {vv }, nil
114+ case httpsfv.InnerList :
115+ vv , err := httpsfv .Marshal (v .(httpsfv.InnerList ))
116+ if err != nil {
117+ return nil , fmt .Errorf ("malformed dictionry member %s: %v" , hdr , err )
118+ }
119+ return []string {vv }, nil
120+ default :
121+ return nil , fmt .Errorf ("unexpected dictionary value" )
122+ }
123+ }
124+
68125func generateSigParams (config * SignConfig , keyID , alg string , foreignSigner interface {}, fields Fields ) (string , error ) {
69126 p := httpsfv .NewParams ()
70127 var createdTime int64
@@ -126,23 +183,23 @@ func SignResponse(signatureName string, signer Signer, res *http.Response) (sign
126183 if err != nil {
127184 return "" , "" , err
128185 }
129- extendedFields := addPseudoHeaders (parsedMessage , signer .config .requestResponse , signer .fields )
130- return signMessage (* signer .config , signatureName , signer , * parsedMessage , extendedFields )
186+ // extendedFields := addPseudoHeaders(parsedMessage, signer.config.requestResponse, signer.fields)
187+ return signMessage (* signer .config , signatureName , signer , * parsedMessage , signer . fields )
131188}
132189
133190// Handle the special header-like @request-response
134- func addPseudoHeaders (message * parsedMessage , rr * requestResponse , fields Fields ) Fields {
135- if rr != nil {
136- rrfield := field {
137- name : "@request-response" ,
138- flagName : "key" ,
139- flagValue : rr .name ,
140- }
141- message .components [rrfield ] = []string {rr .signature }
142- return append (fields , rrfield )
143- }
144- return fields
145- }
191+ // func addPseudoHeaders(message *parsedMessage, rr *requestResponse, fields Fields) Fields {
192+ // if rr != nil {
193+ // rrfield := field{
194+ // name: "@request-response",
195+ // flagName: "key",
196+ // flagValue: rr.name,
197+ // }
198+ // message.components[rrfield] = []string{rr.signature}
199+ // return append(fields, rrfield)
200+ // }
201+ // return fields
202+ // }
146203
147204//
148205// VerifyRequest verifies a signed HTTP request. Returns an error if verification failed for any reason, otherwise nil.
@@ -207,8 +264,8 @@ func GetRequestSignature(req *http.Request, signatureName string) (string, error
207264 if err != nil {
208265 return "" , err
209266 }
210- ws , found := parsedMessage .components [ * fromDictHeader ("signature" , signatureName )]
211- if ! found {
267+ ws , err := parsedMessage .getDictHeader ("signature" , signatureName )
268+ if err != nil {
212269 return "" , fmt .Errorf ("missing \" signature\" header for \" %s\" " , signatureName )
213270 }
214271 if len (ws ) > 1 {
@@ -223,8 +280,8 @@ func GetRequestSignature(req *http.Request, signatureName string) (string, error
223280}
224281
225282func messageKeyID (signatureName string , parsedMessage parsedMessage ) (keyID , alg string , err error ) {
226- si , found := parsedMessage .components [ * fromDictHeader ("signature-input" , signatureName )]
227- if ! found {
283+ si , err := parsedMessage .getDictHeader ("signature-input" , signatureName )
284+ if err != nil {
228285 return "" , "" , fmt .Errorf ("missing \" signature-input\" header, or cannot find \" %s\" " , signatureName )
229286 }
230287 if len (si ) > 1 {
@@ -267,29 +324,29 @@ func VerifyResponse(signatureName string, verifier Verifier, res *http.Response)
267324 if err != nil {
268325 return err
269326 }
270- extendedFields := addPseudoHeaders (parsedMessage , verifier .config .requestResponse , verifier .fields )
271- return verifyMessage (* verifier .config , signatureName , verifier , * parsedMessage , extendedFields )
327+ // extendedFields := addPseudoHeaders(parsedMessage, verifier.config.requestResponse, verifier.fields)
328+ return verifyMessage (* verifier .config , signatureName , verifier , * parsedMessage , verifier . fields )
272329}
273330
274331func verifyMessage (config VerifyConfig , name string , verifier Verifier , message parsedMessage , fields Fields ) error {
275- wsi , found := message .components [ * fromDictHeader ("signature-input" , name )]
276- if ! found {
332+ wsi , err := message .getDictHeader ("signature-input" , name )
333+ if err != nil {
277334 return fmt .Errorf ("missing \" signature-input\" header, or cannot find signature \" %s\" " , name )
278335 }
279336 if len (wsi ) > 1 {
280337 return fmt .Errorf ("multiple \" signature-header\" values for %s" , name )
281338 }
282339 wantSignatureInput := wsi [0 ]
283- ws , found := message .components [ * fromDictHeader ("signature" , name )]
284- if ! found {
340+ ws , err := message .getDictHeader ("signature" , name )
341+ if err != nil {
285342 return fmt .Errorf ("missing \" signature\" header" )
286343 }
287344 if len (ws ) > 1 {
288345 return fmt .Errorf ("multiple \" signature\" values for %s" , name )
289346 }
290347 wantSignature := ws [0 ]
291- delete (message .components , * fromDictHeader ("signature-input" , name ))
292- delete (message .components , * fromDictHeader ("signature" , name ))
348+ // delete(message.components, *fromDictHeader("signature-input", name))
349+ // delete(message.components, *fromDictHeader("signature", name))
293350 wantSigRaw , err := parseWantSignature (wantSignature )
294351 if err != nil {
295352 return err
0 commit comments