func GenerateSignature(c *cli.Context) { url := c.String("url") if url == "" { cli.ShowCommandHelp(c, "generate") os.Exit(1) } crypto, err := common.CreateCrypto(c) if err != nil { os.Exit(1) } signature, err := createSigFromArgs(c) if err != nil { os.Exit(1) } sigEncoded, metaEncoded, err := header.BuildSignatureAndMetadata(crypto, &signature) if err != nil { fmt.Printf("Failed to create signature: %s", err.Error()) os.Exit(1) } fmt.Printf("Encoded Signature:\n%s\n\n", sigEncoded) fmt.Printf("Encoded Metadata:\n%s\n\n", metaEncoded) }
func (rs *RouteServiceConfig) generateSignatureAndMetadata(forwardedUrlRaw string) (string, string, error) { decodedURL, err := url.QueryUnescape(forwardedUrlRaw) if err != nil { rs.logger.Error("proxy.route-service.invalidForwardedURL", err) return "", "", err } signature := &header.Signature{ RequestedTime: time.Now(), ForwardedUrl: decodedURL, } signatureHeader, metadataHeader, err := header.BuildSignatureAndMetadata(rs.crypto, signature) if err != nil { return "", "", err } return signatureHeader, metadataHeader, nil }
return []byte(decryptedStr), nil } crypto.EncryptStub = func(plainText []byte) ([]byte, []byte, error) { nonce := []byte("some-nonce") cipherText := append(plainText, "encrypted"...) cipherText = append(cipherText, nonce...) return cipherText, nonce, nil } signature = &header.Signature{RequestedTime: time.Now()} }) Describe("Build Signature and Metadata", func() { It("builds signature and metadata headers", func() { signatureHeader, metadata, err := header.BuildSignatureAndMetadata(crypto, signature) Expect(err).ToNot(HaveOccurred()) Expect(signatureHeader).ToNot(BeNil()) metadataDecoded, err := base64.URLEncoding.DecodeString(metadata) Expect(err).ToNot(HaveOccurred()) metadataStruct := header.Metadata{} err = json.Unmarshal([]byte(metadataDecoded), &metadataStruct) Expect(err).ToNot(HaveOccurred()) Expect(metadataStruct.Nonce).To(Equal([]byte("some-nonce"))) }) Context("when unable to encrypt the signature", func() { BeforeEach(func() { crypto.EncryptReturns([]byte{}, []byte{}, errors.New("No entropy")) })
req.Header.Set(routeservice.RouteServiceSignature, signatureHeader) req.Header.Set(routeservice.RouteServiceMetadata, metadataHeader) conn.WriteRequest(req) res, body := conn.ReadResponse() Expect(res.StatusCode).To(Equal(http.StatusOK)) Expect(body).To(ContainSubstring("backend instance")) }) Context("when a request has an expired Route service signature header", func() { BeforeEach(func() { signature := &header.Signature{ RequestedTime: time.Now().Add(-10 * time.Hour), ForwardedUrl: forwardedUrl, } signatureHeader, metadataHeader, _ = header.BuildSignatureAndMetadata(crypto, signature) }) It("returns an route service request expired error", func() { ln := registerHandlerWithRouteService(r, "my_host.com", "https://expired.com", func(conn *test_util.HttpConn) { Fail("Should not get here") }) defer ln.Close() conn := dialProxy(proxyServer) req := test_util.NewRequest("GET", "my_host.com", "/resource+9-9_9?query=123&query$2=345#page1..5", nil) req.Header.Set(routeservice.RouteServiceSignature, signatureHeader) req.Header.Set(routeservice.RouteServiceMetadata, metadataHeader) req.Header.Set(routeservice.RouteServiceForwardedURL, forwardedUrl) conn.WriteRequest(req)