validSignature returns whether the request signature is valid.
(key []byte, r *Request)
| 456 | |
| 457 | // validSignature returns whether the request signature is valid. |
| 458 | func validSignature(key []byte, r *Request) bool { |
| 459 | sig := r.Options.Signature |
| 460 | if m := len(sig) % 4; m != 0 { // add padding if missing |
| 461 | sig += strings.Repeat("=", 4-m) |
| 462 | } |
| 463 | |
| 464 | got, err := base64.URLEncoding.DecodeString(sig) |
| 465 | if err != nil { |
| 466 | log.Printf("error base64 decoding signature %q", r.Options.Signature) |
| 467 | return false |
| 468 | } |
| 469 | |
| 470 | // check signature with URL only |
| 471 | mac := hmac.New(sha256.New, key) |
| 472 | _, _ = mac.Write([]byte(r.URL.String())) |
| 473 | want := mac.Sum(nil) |
| 474 | if hmac.Equal(got, want) { |
| 475 | return true |
| 476 | } |
| 477 | |
| 478 | // check signature with URL and options |
| 479 | u, opt := *r.URL, r.Options // make copies |
| 480 | opt.Signature = "" |
| 481 | u.Fragment = opt.String() |
| 482 | |
| 483 | mac = hmac.New(sha256.New, key) |
| 484 | _, _ = mac.Write([]byte(u.String())) |
| 485 | want = mac.Sum(nil) |
| 486 | return hmac.Equal(got, want) |
| 487 | } |
| 488 | |
| 489 | // should304 returns whether we should send a 304 Not Modified in response to |
| 490 | // req, based on the response resp. This is determined using the last modified |