func (rs *RouteServiceConfig) ValidateSignature(headers *http.Header, requestUrl string) error { metadataHeader := headers.Get(RouteServiceMetadata) signatureHeader := headers.Get(RouteServiceSignature) signature, err := header.SignatureFromHeaders(signatureHeader, metadataHeader, rs.crypto) if err != nil { rs.logger.Error("proxy.route-service.current_key", err) // Decrypt the head again trying to use the old key. if rs.cryptoPrev != nil { rs.logger.Error("proxy.route-service.current_key", err) signature, err = header.SignatureFromHeaders(signatureHeader, metadataHeader, rs.cryptoPrev) if err != nil { rs.logger.Error("proxy.route-service.previous_key", err) } } return err } err = rs.validateSignatureTimeout(signature) if err != nil { return err } return rs.validateForwardedURL(signature, requestUrl) }
func ReadSignature(c *cli.Context) { sigEncoded := c.String("signature") metaEncoded := c.String("metadata") if sigEncoded == "" || metaEncoded == "" { cli.ShowCommandHelp(c, "read") os.Exit(1) } crypto, err := common.CreateCrypto(c) if err != nil { os.Exit(1) } signature, err := header.SignatureFromHeaders(sigEncoded, metaEncoded, crypto) if err != nil { fmt.Printf("Failed to read signature: %s\n", err.Error()) os.Exit(1) } printSignature(signature) }
crypto.EncryptReturns([]byte{}, []byte{}, errors.New("No entropy")) }) It("returns an error", func() { _, _, err := header.BuildSignatureAndMetadata(crypto, signature) Expect(err).To(HaveOccurred()) }) }) }) Describe("Parse signature from headers", func() { var ( signatureHeader string metadataHeader string ) BeforeEach(func() { var err error signatureHeader, metadataHeader, err = header.BuildSignatureAndMetadata(crypto, signature) Expect(err).ToNot(HaveOccurred()) }) It("parses signature from signature and metadata headers", func() { decryptedSignature, err := header.SignatureFromHeaders(signatureHeader, metadataHeader, crypto) Expect(err).ToNot(HaveOccurred()) Expect(signature.RequestedTime.Sub(decryptedSignature.RequestedTime)).To(Equal(time.Duration(0))) }) }) })
Expect(err).ToNot(HaveOccurred()) }() }) BeforeEach(func() { conf.RouteServiceEnabled = true recommendHttps = true forwardedUrl = "https://my_host.com/resource+9-9_9?query=123&query$2=345#page1..5" routeServiceHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { metaHeader := r.Header.Get(routeservice.RouteServiceMetadata) sigHeader := r.Header.Get(routeservice.RouteServiceSignature) crypto, err := secure.NewAesGCM([]byte(cryptoKey)) Expect(err).ToNot(HaveOccurred()) _, err = header.SignatureFromHeaders(sigHeader, metaHeader, crypto) Expect(err).ToNot(HaveOccurred()) Expect(r.Header.Get("X-CF-ApplicationID")).To(Equal("")) // validate client request header Expect(r.Header.Get("X-CF-Forwarded-Url")).To(Equal(forwardedUrl)) w.Write([]byte("My Special Snowflake Route Service\n")) }) crypto, err := secure.NewAesGCM([]byte(cryptoKey)) Expect(err).ToNot(HaveOccurred()) config := routeservice.NewRouteServiceConfig( logger,
AfterEach(func() { crypto = nil cryptoPrev = nil config = nil }) Describe("Request", func() { It("decodes an encoded URL", func() { encodedForwardedURL := url.QueryEscape("test.app.com?query=sample") rsUrl := "https://example.com" args, err := config.Request(rsUrl, encodedForwardedURL) Expect(err).NotTo(HaveOccurred()) signature, err := header.SignatureFromHeaders(args.Signature, args.Metadata, crypto) Expect(err).ToNot(HaveOccurred()) Expect(signature.ForwardedUrl).ToNot(BeEmpty()) }) It("sets the requested time", func() { encodedForwardedURL := url.QueryEscape("test.app.com?query=sample") now := time.Now() rsUrl := "https://example.com" args, err := config.Request(rsUrl, encodedForwardedURL) Expect(err).NotTo(HaveOccurred()) signature, err := header.SignatureFromHeaders(args.Signature, args.Metadata, crypto) Expect(err).ToNot(HaveOccurred())