[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nbin\n.idea/\n\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: go\n\nscript:\n    - go vet ./...\n    - go test -v ./...\n\ngo:\n  - 1.3\n  - 1.4\n  - 1.5\n  - 1.6\n  - 1.7\n  - tip\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2012 Dave Grijalva\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "MIGRATION_GUIDE.md",
    "content": "## Migration Guide from v2 -> v3\n\nVersion 3 adds several new, frequently requested features.  To do so, it introduces a few breaking changes.  We've worked to keep these as minimal as possible.  This guide explains the breaking changes and how you can quickly update your code.\n\n### `Token.Claims` is now an interface type\n\nThe most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`.  We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`.\n\n`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior.  It is the default claims type when using `Parse`.  The usage is unchanged except you must type cast the claims property.\n\nThe old example for parsing a token looked like this..\n\n```go\n\tif token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {\n\t\tfmt.Printf(\"Token for user %v expires %v\", token.Claims[\"user\"], token.Claims[\"exp\"])\n\t}\n```\n\nis now directly mapped to...\n\n```go\n\tif token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {\n\t\tclaims := token.Claims.(jwt.MapClaims)\n\t\tfmt.Printf(\"Token for user %v expires %v\", claims[\"user\"], claims[\"exp\"])\n\t}\n```\n\n`StandardClaims` is designed to be embedded in your custom type.  You can supply a custom claims type with the new `ParseWithClaims` function.  Here's an example of using a custom claims type.\n\n```go\n\ttype MyCustomClaims struct {\n\t\tUser string\n\t\t*StandardClaims\n\t}\n\t\n\tif token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil {\n\t\tclaims := token.Claims.(*MyCustomClaims)\n\t\tfmt.Printf(\"Token for user %v expires %v\", claims.User, claims.StandardClaims.ExpiresAt)\n\t}\n```\n\n### `ParseFromRequest` has been moved\n\nTo keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`.  The method signatues have also been augmented to receive a new argument: `Extractor`.\n\n`Extractors` do the work of picking the token string out of a request.  The interface is simple and composable.\n\nThis simple parsing example:\n\n```go\n\tif token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil {\n\t\tfmt.Printf(\"Token for user %v expires %v\", token.Claims[\"user\"], token.Claims[\"exp\"])\n\t}\n```\n\nis directly mapped to:\n\n```go\n\tif token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil {\n\t\tclaims := token.Claims.(jwt.MapClaims)\n\t\tfmt.Printf(\"Token for user %v expires %v\", claims[\"user\"], claims[\"exp\"])\n\t}\n```\n\nThere are several concrete `Extractor` types provided for your convenience:\n\n* `HeaderExtractor` will search a list of headers until one contains content.\n* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content.\n* `MultiExtractor` will try a list of `Extractors` in order until one returns content.\n* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token.\n* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument\n* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed.  A simple example is stripping the `Bearer ` text from a header\n\n\n### RSA signing methods no longer accept `[]byte` keys\n\nDue to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse.\n\nTo replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`.  These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types.\n\n```go \n\tfunc keyLookupFunc(*Token) (interface{}, error) {\n\t\t// Don't forget to validate the alg is what you expect:\n\t\tif _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {\n\t\t\treturn nil, fmt.Errorf(\"Unexpected signing method: %v\", token.Header[\"alg\"])\n\t\t}\n\t\t\n\t\t// Look up key \n\t\tkey, err := lookupPublicKey(token.Header[\"kid\"])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t\n\t\t// Unpack key from PEM encoded PKCS8\n\t\treturn jwt.ParseRSAPublicKeyFromPEM(key)\n\t}\n```\n"
  },
  {
    "path": "README.md",
    "content": "# THIS REPOSITORY IS NO LONGER MAINTANED\n\nThe new repository can be found at: https://github.com/golang-jwt/jwt\n\nFor more information, see issue [#462](https://github.com/dgrijalva/jwt-go/issues/462).\n\n# jwt-go\n\n[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go)\n[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go)\n\nA [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html)\n\n**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. \n\n**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail.\n\n**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage.  See the examples provided.\n\n## What the heck is a JWT?\n\nJWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens.\n\nIn short, it's a signed JSON object that does something useful (for example, authentication).  It's commonly used for `Bearer` tokens in Oauth 2.  A token is made of three parts, separated by `.`'s.  The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded.  The last part is the signature, encoded the same way.\n\nThe first part is called the header.  It contains the necessary information for verifying the last part, the signature.  For example, which encryption method was used for signing and what key was used.\n\nThe part in the middle is the interesting bit.  It's called the Claims and contains the actual stuff you care about.  Refer to [the RFC](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) for information about reserved keys and the proper way to add your own.\n\n## What's in the box?\n\nThis library supports the parsing and verification as well as the generation and signing of JWTs.  Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.\n\n## Examples\n\nSee [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage:\n\n* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)\n* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)\n* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)\n\n## Extensions\n\nThis library publishes all the necessary components for adding your own signing methods.  Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.  \n\nHere's an example of an extension that integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS): https://github.com/someone1/gcp-jwt-go\n\n## Compliance\n\nThis library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences:\n\n* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.\n\n## Project Status & Versioning\n\nThis library is considered production ready.  Feedback and feature requests are appreciated.  The API should be considered stable.  There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).\n\nThis project uses [Semantic Versioning 2.0.0](http://semver.org).  Accepted pull requests will land on `master`.  Periodically, versions will be tagged from `master`.  You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases).\n\nWhile we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users.  You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`.  It will do the right thing WRT semantic versioning.\n\n**BREAKING CHANGES:*** \n* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API.  We've tried to break as few things as possible, so there should just be a few type signature changes.  A full list of breaking changes is available in `VERSION_HISTORY.md`.  See `MIGRATION_GUIDE.md` for more information on updating your code.\n\n## Usage Tips\n\n### Signing vs Encryption\n\nA token is simply a JSON object that is signed by its author. this tells you exactly two things about the data:\n\n* The author of the token was in the possession of the signing secret\n* The data has not been modified since it was signed\n\nIt's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library.\n\n### Choosing a Signing Method\n\nThere are several signing methods available, and you should probably take the time to learn about the various options before choosing one.  The principal design decision is most likely going to be symmetric vs asymmetric.\n\nSymmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation.\n\nAsymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification.\n\n### Signing Methods and Key Types\n\nEach signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones:\n\n* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation\n* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation\n* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation\n\n### JWT and OAuth\n\nIt's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication.\n\nWithout going too far down the rabbit hole, here's a description of the interaction of these technologies:\n\n* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth.\n* OAuth defines several options for passing around authentication data. One popular method is called a \"bearer token\". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.\n* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.\n\n### Troubleshooting\n\nThis library uses descriptive error messages whenever possible. If you are not getting the expected result, have a look at the errors. The most common place people get stuck is providing the correct type of key to the parser. See the above section on signing methods and key types.\n\n## More\n\nDocumentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go).\n\nThe command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation.\n"
  },
  {
    "path": "VERSION_HISTORY.md",
    "content": "## `jwt-go` Version History\n\n#### 3.2.0\n\n* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation\n* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate\n* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before.\n* Deprecated `ParseFromRequestWithClaims` to simplify API in the future.\n\n#### 3.1.0\n\n* Improvements to `jwt` command line tool\n* Added `SkipClaimsValidation` option to `Parser`\n* Documentation updates\n\n#### 3.0.0\n\n* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code\n\t* Dropped support for `[]byte` keys when using RSA signing methods.  This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods.\n\t* `ParseFromRequest` has been moved to `request` subpackage and usage has changed\n\t* The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`.  The default value is type `MapClaims`, which is an alias to `map[string]interface{}`.  This makes it possible to use a custom type when decoding claims.\n* Other Additions and Changes\n\t* Added `Claims` interface type to allow users to decode the claims into a custom type\n\t* Added `ParseWithClaims`, which takes a third argument of type `Claims`.  Use this function instead of `Parse` if you have a custom type you'd like to decode into.\n\t* Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage\n\t* Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims`\n\t* Added new interface type `Extractor`, which is used for extracting JWT strings from http requests.  Used with `ParseFromRequest` and `ParseFromRequestWithClaims`.\n\t* Added several new, more specific, validation errors to error type bitmask\n\t* Moved examples from README to executable example files\n\t* Signing method registry is now thread safe\n\t* Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser)\n\n#### 2.7.0\n\nThis will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes.\n\n* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying\n* Error text for expired tokens includes how long it's been expired\n* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM`\n* Documentation updates\n\n#### 2.6.0\n\n* Exposed inner error within ValidationError\n* Fixed validation errors when using UseJSONNumber flag\n* Added several unit tests\n\n#### 2.5.0\n\n* Added support for signing method none.  You shouldn't use this.  The API tries to make this clear.\n* Updated/fixed some documentation\n* Added more helpful error message when trying to parse tokens that begin with `BEARER `\n\n#### 2.4.0\n\n* Added new type, Parser, to allow for configuration of various parsing parameters\n\t* You can now specify a list of valid signing methods.  Anything outside this set will be rejected.\n\t* You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON\n* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go)\n* Fixed some bugs with ECDSA parsing\n\n#### 2.3.0\n\n* Added support for ECDSA signing methods\n* Added support for RSA PSS signing methods (requires go v1.4)\n\n#### 2.2.0\n\n* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`.  Result will now be the parsed token and an error, instead of a panic.\n\n#### 2.1.0\n\nBackwards compatible API change that was missed in 2.0.0.\n\n* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte`\n\n#### 2.0.0\n\nThere were two major reasons for breaking backwards compatibility with this update.  The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations.  There will likely be no required code changes to support this change.\n\nThe second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods.  Not all keys used for all signing methods have a single standard on-disk representation.  Requiring `[]byte` as the type for all keys proved too limiting.  Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys.  Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`.\n\nIt is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`.\n\n* **Compatibility Breaking Changes**\n\t* `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct`\n\t* `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct`\n\t* `KeyFunc` now returns `interface{}` instead of `[]byte`\n\t* `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key\n\t* `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key\n* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`.  Specific sizes are now just instances of this type.\n    * Added public package global `SigningMethodHS256`\n    * Added public package global `SigningMethodHS384`\n    * Added public package global `SigningMethodHS512`\n* Renamed type `SigningMethodRS256` to `SigningMethodRSA`.  Specific sizes are now just instances of this type.\n    * Added public package global `SigningMethodRS256`\n    * Added public package global `SigningMethodRS384`\n    * Added public package global `SigningMethodRS512`\n* Moved sample private key for HMAC tests from an inline value to a file on disk.  Value is unchanged.\n* Refactored the RSA implementation to be easier to read\n* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM`\n\n#### 1.0.2\n\n* Fixed bug in parsing public keys from certificates\n* Added more tests around the parsing of keys for RS256\n* Code refactoring in RS256 implementation.  No functional changes\n\n#### 1.0.1\n\n* Fixed panic if RS256 signing method was passed an invalid key\n\n#### 1.0.0\n\n* First versioned release\n* API stabilized\n* Supports creating, signing, parsing, and validating JWT tokens\n* Supports RS256 and HS256 signing methods"
  },
  {
    "path": "claims.go",
    "content": "package jwt\n\nimport (\n\t\"crypto/subtle\"\n\t\"fmt\"\n\t\"time\"\n)\n\n// For a type to be a Claims object, it must just have a Valid method that determines\n// if the token is invalid for any supported reason\ntype Claims interface {\n\tValid() error\n}\n\n// Structured version of Claims Section, as referenced at\n// https://tools.ietf.org/html/rfc7519#section-4.1\n// See examples for how to use this with your own claim types\ntype StandardClaims struct {\n\tAudience  string `json:\"aud,omitempty\"`\n\tExpiresAt int64  `json:\"exp,omitempty\"`\n\tId        string `json:\"jti,omitempty\"`\n\tIssuedAt  int64  `json:\"iat,omitempty\"`\n\tIssuer    string `json:\"iss,omitempty\"`\n\tNotBefore int64  `json:\"nbf,omitempty\"`\n\tSubject   string `json:\"sub,omitempty\"`\n}\n\n// Validates time based claims \"exp, iat, nbf\".\n// There is no accounting for clock skew.\n// As well, if any of the above claims are not in the token, it will still\n// be considered a valid claim.\nfunc (c StandardClaims) Valid() error {\n\tvErr := new(ValidationError)\n\tnow := TimeFunc().Unix()\n\n\t// The claims below are optional, by default, so if they are set to the\n\t// default value in Go, let's not fail the verification for them.\n\tif c.VerifyExpiresAt(now, false) == false {\n\t\tdelta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))\n\t\tvErr.Inner = fmt.Errorf(\"token is expired by %v\", delta)\n\t\tvErr.Errors |= ValidationErrorExpired\n\t}\n\n\tif c.VerifyIssuedAt(now, false) == false {\n\t\tvErr.Inner = fmt.Errorf(\"Token used before issued\")\n\t\tvErr.Errors |= ValidationErrorIssuedAt\n\t}\n\n\tif c.VerifyNotBefore(now, false) == false {\n\t\tvErr.Inner = fmt.Errorf(\"token is not valid yet\")\n\t\tvErr.Errors |= ValidationErrorNotValidYet\n\t}\n\n\tif vErr.valid() {\n\t\treturn nil\n\t}\n\n\treturn vErr\n}\n\n// Compares the aud claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {\n\treturn verifyAud([]string{c.Audience}, cmp, req)\n}\n\n// Compares the exp claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {\n\treturn verifyExp(c.ExpiresAt, cmp, req)\n}\n\n// Compares the iat claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {\n\treturn verifyIat(c.IssuedAt, cmp, req)\n}\n\n// Compares the iss claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {\n\treturn verifyIss(c.Issuer, cmp, req)\n}\n\n// Compares the nbf claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {\n\treturn verifyNbf(c.NotBefore, cmp, req)\n}\n\n// ----- helpers\n\nfunc verifyAud(aud []string, cmp string, required bool) bool {\n\tif len(aud) == 0 {\n\t\treturn !required\n\t}\n\t// use a var here to keep constant time compare when looping over a number of claims\n\tresult := false\n\n\tvar stringClaims string\n\tfor _, a := range aud {\n\t\tif subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {\n\t\t\tresult = true\n\t\t}\n\t\tstringClaims = stringClaims + a\n\t}\n\n\t// case where \"\" is sent in one or many aud claims\n\tif len(stringClaims) == 0 {\n\t\treturn !required\n\t}\n\n\treturn result\n}\n\nfunc verifyExp(exp int64, now int64, required bool) bool {\n\tif exp == 0 {\n\t\treturn !required\n\t}\n\treturn now <= exp\n}\n\nfunc verifyIat(iat int64, now int64, required bool) bool {\n\tif iat == 0 {\n\t\treturn !required\n\t}\n\treturn now >= iat\n}\n\nfunc verifyIss(iss string, cmp string, required bool) bool {\n\tif iss == \"\" {\n\t\treturn !required\n\t}\n\tif subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 {\n\t\treturn true\n\t} else {\n\t\treturn false\n\t}\n}\n\nfunc verifyNbf(nbf int64, now int64, required bool) bool {\n\tif nbf == 0 {\n\t\treturn !required\n\t}\n\treturn now >= nbf\n}\n"
  },
  {
    "path": "cmd/jwt/README.md",
    "content": "`jwt` command-line tool\n=======================\n\nThis is a simple tool to sign, verify and show JSON Web Tokens from\nthe command line.\n\nThe following will create and sign a token, then verify it and output the original claims:\n\n     echo {\\\"foo\\\":\\\"bar\\\"} | ./jwt -key ../../test/sample_key -alg RS256 -sign - | ./jwt -key ../../test/sample_key.pub -alg RS256 -verify -\n\nKey files should be in PEM format. Other formats are not supported by this tool.\n\nTo simply display a token, use:\n\n    echo $JWT | ./jwt -show -\n\nYou can install this tool with the following command:\n\n     go install github.com/dgrijalva/jwt-go/cmd/jwt\n\n"
  },
  {
    "path": "cmd/jwt/app.go",
    "content": "// A useful example app.  You can use this to debug your tokens on the command line.\n// This is also a great place to look at how you might use this library.\n//\n// Example usage:\n// The following will create and sign a token, then verify it and output the original claims.\n//     echo {\\\"foo\\\":\\\"bar\\\"} | bin/jwt -key test/sample_key -alg RS256 -sign - | bin/jwt -key test/sample_key.pub -verify -\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\n\tjwt \"github.com/dgrijalva/jwt-go\"\n)\n\nvar (\n\t// Options\n\tflagAlg     = flag.String(\"alg\", \"\", \"signing algorithm identifier\")\n\tflagKey     = flag.String(\"key\", \"\", \"path to key file or '-' to read from stdin\")\n\tflagCompact = flag.Bool(\"compact\", false, \"output compact JSON\")\n\tflagDebug   = flag.Bool(\"debug\", false, \"print out all kinds of debug data\")\n\tflagClaims  = make(ArgList)\n\tflagHead    = make(ArgList)\n\n\t// Modes - exactly one of these is required\n\tflagSign   = flag.String(\"sign\", \"\", \"path to claims object to sign, '-' to read from stdin, or '+' to use only -claim args\")\n\tflagVerify = flag.String(\"verify\", \"\", \"path to JWT token to verify or '-' to read from stdin\")\n\tflagShow   = flag.String(\"show\", \"\", \"path to JWT file or '-' to read from stdin\")\n)\n\nfunc main() {\n\t// Plug in Var flags\n\tflag.Var(flagClaims, \"claim\", \"add additional claims. may be used more than once\")\n\tflag.Var(flagHead, \"header\", \"add additional header params. may be used more than once\")\n\n\t// Usage message if you ask for -help or if you mess up inputs.\n\tflag.Usage = func() {\n\t\tfmt.Fprintf(os.Stderr, \"Usage of %s:\\n\", os.Args[0])\n\t\tfmt.Fprintf(os.Stderr, \"  One of the following flags is required: sign, verify\\n\")\n\t\tflag.PrintDefaults()\n\t}\n\n\t// Parse command line options\n\tflag.Parse()\n\n\t// Do the thing.  If something goes wrong, print error to stderr\n\t// and exit with a non-zero status code\n\tif err := start(); err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Error: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n}\n\n// Figure out which thing to do and then do that\nfunc start() error {\n\tif *flagSign != \"\" {\n\t\treturn signToken()\n\t} else if *flagVerify != \"\" {\n\t\treturn verifyToken()\n\t} else if *flagShow != \"\" {\n\t\treturn showToken()\n\t} else {\n\t\tflag.Usage()\n\t\treturn fmt.Errorf(\"None of the required flags are present.  What do you want me to do?\")\n\t}\n}\n\n// Helper func:  Read input from specified file or stdin\nfunc loadData(p string) ([]byte, error) {\n\tif p == \"\" {\n\t\treturn nil, fmt.Errorf(\"No path specified\")\n\t}\n\n\tvar rdr io.Reader\n\tif p == \"-\" {\n\t\trdr = os.Stdin\n\t} else if p == \"+\" {\n\t\treturn []byte(\"{}\"), nil\n\t} else {\n\t\tif f, err := os.Open(p); err == nil {\n\t\t\trdr = f\n\t\t\tdefer f.Close()\n\t\t} else {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn ioutil.ReadAll(rdr)\n}\n\n// Print a json object in accordance with the prophecy (or the command line options)\nfunc printJSON(j interface{}) error {\n\tvar out []byte\n\tvar err error\n\n\tif *flagCompact == false {\n\t\tout, err = json.MarshalIndent(j, \"\", \"    \")\n\t} else {\n\t\tout, err = json.Marshal(j)\n\t}\n\n\tif err == nil {\n\t\tfmt.Println(string(out))\n\t}\n\n\treturn err\n}\n\n// Verify a token and output the claims.  This is a great example\n// of how to verify and view a token.\nfunc verifyToken() error {\n\t// get the token\n\ttokData, err := loadData(*flagVerify)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't read token: %v\", err)\n\t}\n\n\t// trim possible whitespace from token\n\ttokData = regexp.MustCompile(`\\s*$`).ReplaceAll(tokData, []byte{})\n\tif *flagDebug {\n\t\tfmt.Fprintf(os.Stderr, \"Token len: %v bytes\\n\", len(tokData))\n\t}\n\n\t// Parse the token.  Load the key from command line option\n\ttoken, err := jwt.Parse(string(tokData), func(t *jwt.Token) (interface{}, error) {\n\t\tdata, err := loadData(*flagKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif isEs() {\n\t\t\treturn jwt.ParseECPublicKeyFromPEM(data)\n\t\t} else if isRs() {\n\t\t\treturn jwt.ParseRSAPublicKeyFromPEM(data)\n\t\t}\n\t\treturn data, nil\n\t})\n\n\t// Print some debug data\n\tif *flagDebug && token != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Header:\\n%v\\n\", token.Header)\n\t\tfmt.Fprintf(os.Stderr, \"Claims:\\n%v\\n\", token.Claims)\n\t}\n\n\t// Print an error if we can't parse for some reason\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't parse token: %v\", err)\n\t}\n\n\t// Is token invalid?\n\tif !token.Valid {\n\t\treturn fmt.Errorf(\"Token is invalid\")\n\t}\n\n\t// Print the token details\n\tif err := printJSON(token.Claims); err != nil {\n\t\treturn fmt.Errorf(\"Failed to output claims: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// Create, sign, and output a token.  This is a great, simple example of\n// how to use this library to create and sign a token.\nfunc signToken() error {\n\t// get the token data from command line arguments\n\ttokData, err := loadData(*flagSign)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't read token: %v\", err)\n\t} else if *flagDebug {\n\t\tfmt.Fprintf(os.Stderr, \"Token: %v bytes\", len(tokData))\n\t}\n\n\t// parse the JSON of the claims\n\tvar claims jwt.MapClaims\n\tif err := json.Unmarshal(tokData, &claims); err != nil {\n\t\treturn fmt.Errorf(\"Couldn't parse claims JSON: %v\", err)\n\t}\n\n\t// add command line claims\n\tif len(flagClaims) > 0 {\n\t\tfor k, v := range flagClaims {\n\t\t\tclaims[k] = v\n\t\t}\n\t}\n\n\t// get the key\n\tvar key interface{}\n\tkey, err = loadData(*flagKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't read key: %v\", err)\n\t}\n\n\t// get the signing alg\n\talg := jwt.GetSigningMethod(*flagAlg)\n\tif alg == nil {\n\t\treturn fmt.Errorf(\"Couldn't find signing method: %v\", *flagAlg)\n\t}\n\n\t// create a new token\n\ttoken := jwt.NewWithClaims(alg, claims)\n\n\t// add command line headers\n\tif len(flagHead) > 0 {\n\t\tfor k, v := range flagHead {\n\t\t\ttoken.Header[k] = v\n\t\t}\n\t}\n\n\tif isEs() {\n\t\tif k, ok := key.([]byte); !ok {\n\t\t\treturn fmt.Errorf(\"Couldn't convert key data to key\")\n\t\t} else {\n\t\t\tkey, err = jwt.ParseECPrivateKeyFromPEM(k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t} else if isRs() {\n\t\tif k, ok := key.([]byte); !ok {\n\t\t\treturn fmt.Errorf(\"Couldn't convert key data to key\")\n\t\t} else {\n\t\t\tkey, err = jwt.ParseRSAPrivateKeyFromPEM(k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tif out, err := token.SignedString(key); err == nil {\n\t\tfmt.Println(out)\n\t} else {\n\t\treturn fmt.Errorf(\"Error signing token: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// showToken pretty-prints the token on the command line.\nfunc showToken() error {\n\t// get the token\n\ttokData, err := loadData(*flagShow)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Couldn't read token: %v\", err)\n\t}\n\n\t// trim possible whitespace from token\n\ttokData = regexp.MustCompile(`\\s*$`).ReplaceAll(tokData, []byte{})\n\tif *flagDebug {\n\t\tfmt.Fprintf(os.Stderr, \"Token len: %v bytes\\n\", len(tokData))\n\t}\n\n\ttoken, err := jwt.Parse(string(tokData), nil)\n\tif token == nil {\n\t\treturn fmt.Errorf(\"malformed token: %v\", err)\n\t}\n\n\t// Print the token details\n\tfmt.Println(\"Header:\")\n\tif err := printJSON(token.Header); err != nil {\n\t\treturn fmt.Errorf(\"Failed to output header: %v\", err)\n\t}\n\n\tfmt.Println(\"Claims:\")\n\tif err := printJSON(token.Claims); err != nil {\n\t\treturn fmt.Errorf(\"Failed to output claims: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc isEs() bool {\n\treturn strings.HasPrefix(*flagAlg, \"ES\")\n}\n\nfunc isRs() bool {\n\treturn strings.HasPrefix(*flagAlg, \"RS\") || strings.HasPrefix(*flagAlg, \"PS\")\n}\n"
  },
  {
    "path": "cmd/jwt/args.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype ArgList map[string]string\n\nfunc (l ArgList) String() string {\n\tdata, _ := json.Marshal(l)\n\treturn string(data)\n}\n\nfunc (l ArgList) Set(arg string) error {\n\tparts := strings.SplitN(arg, \"=\", 2)\n\tif len(parts) != 2 {\n\t\treturn fmt.Errorf(\"Invalid argument '%v'.  Must use format 'key=value'. %v\", arg, parts)\n\t}\n\tl[parts[0]] = parts[1]\n\treturn nil\n}\n"
  },
  {
    "path": "doc.go",
    "content": "// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html\n//\n// See README.md for more info.\npackage jwt\n"
  },
  {
    "path": "ecdsa.go",
    "content": "package jwt\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"math/big\"\n)\n\nvar (\n\t// Sadly this is missing from crypto/ecdsa compared to crypto/rsa\n\tErrECDSAVerification = errors.New(\"crypto/ecdsa: verification error\")\n)\n\n// Implements the ECDSA family of signing methods signing methods\n// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification\ntype SigningMethodECDSA struct {\n\tName      string\n\tHash      crypto.Hash\n\tKeySize   int\n\tCurveBits int\n}\n\n// Specific instances for EC256 and company\nvar (\n\tSigningMethodES256 *SigningMethodECDSA\n\tSigningMethodES384 *SigningMethodECDSA\n\tSigningMethodES512 *SigningMethodECDSA\n)\n\nfunc init() {\n\t// ES256\n\tSigningMethodES256 = &SigningMethodECDSA{\"ES256\", crypto.SHA256, 32, 256}\n\tRegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {\n\t\treturn SigningMethodES256\n\t})\n\n\t// ES384\n\tSigningMethodES384 = &SigningMethodECDSA{\"ES384\", crypto.SHA384, 48, 384}\n\tRegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {\n\t\treturn SigningMethodES384\n\t})\n\n\t// ES512\n\tSigningMethodES512 = &SigningMethodECDSA{\"ES512\", crypto.SHA512, 66, 521}\n\tRegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {\n\t\treturn SigningMethodES512\n\t})\n}\n\nfunc (m *SigningMethodECDSA) Alg() string {\n\treturn m.Name\n}\n\n// Implements the Verify method from SigningMethod\n// For this verify method, key must be an ecdsa.PublicKey struct\nfunc (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {\n\tvar err error\n\n\t// Decode the signature\n\tvar sig []byte\n\tif sig, err = DecodeSegment(signature); err != nil {\n\t\treturn err\n\t}\n\n\t// Get the key\n\tvar ecdsaKey *ecdsa.PublicKey\n\tswitch k := key.(type) {\n\tcase *ecdsa.PublicKey:\n\t\tecdsaKey = k\n\tdefault:\n\t\treturn ErrInvalidKeyType\n\t}\n\n\tif len(sig) != 2*m.KeySize {\n\t\treturn ErrECDSAVerification\n\t}\n\n\tr := big.NewInt(0).SetBytes(sig[:m.KeySize])\n\ts := big.NewInt(0).SetBytes(sig[m.KeySize:])\n\n\t// Create hasher\n\tif !m.Hash.Available() {\n\t\treturn ErrHashUnavailable\n\t}\n\thasher := m.Hash.New()\n\thasher.Write([]byte(signingString))\n\n\t// Verify the signature\n\tif verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {\n\t\treturn nil\n\t} else {\n\t\treturn ErrECDSAVerification\n\t}\n}\n\n// Implements the Sign method from SigningMethod\n// For this signing method, key must be an ecdsa.PrivateKey struct\nfunc (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {\n\t// Get the key\n\tvar ecdsaKey *ecdsa.PrivateKey\n\tswitch k := key.(type) {\n\tcase *ecdsa.PrivateKey:\n\t\tecdsaKey = k\n\tdefault:\n\t\treturn \"\", ErrInvalidKeyType\n\t}\n\n\t// Create the hasher\n\tif !m.Hash.Available() {\n\t\treturn \"\", ErrHashUnavailable\n\t}\n\n\thasher := m.Hash.New()\n\thasher.Write([]byte(signingString))\n\n\t// Sign the string and return r, s\n\tif r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil {\n\t\tcurveBits := ecdsaKey.Curve.Params().BitSize\n\n\t\tif m.CurveBits != curveBits {\n\t\t\treturn \"\", ErrInvalidKey\n\t\t}\n\n\t\tkeyBytes := curveBits / 8\n\t\tif curveBits%8 > 0 {\n\t\t\tkeyBytes += 1\n\t\t}\n\n\t\t// We serialize the outpus (r and s) into big-endian byte arrays and pad\n\t\t// them with zeros on the left to make sure the sizes work out. Both arrays\n\t\t// must be keyBytes long, and the output must be 2*keyBytes long.\n\t\trBytes := r.Bytes()\n\t\trBytesPadded := make([]byte, keyBytes)\n\t\tcopy(rBytesPadded[keyBytes-len(rBytes):], rBytes)\n\n\t\tsBytes := s.Bytes()\n\t\tsBytesPadded := make([]byte, keyBytes)\n\t\tcopy(sBytesPadded[keyBytes-len(sBytes):], sBytes)\n\n\t\tout := append(rBytesPadded, sBytesPadded...)\n\n\t\treturn EncodeSegment(out), nil\n\t} else {\n\t\treturn \"\", err\n\t}\n}\n"
  },
  {
    "path": "ecdsa_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"io/ioutil\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/dgrijalva/jwt-go\"\n)\n\nvar ecdsaTestData = []struct {\n\tname        string\n\tkeys        map[string]string\n\ttokenString string\n\talg         string\n\tclaims      map[string]interface{}\n\tvalid       bool\n}{\n\t{\n\t\t\"Basic ES256\",\n\t\tmap[string]string{\"private\": \"test/ec256-private.pem\", \"public\": \"test/ec256-public.pem\"},\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJmb28iOiJiYXIifQ.feG39E-bn8HXAKhzDZq7yEAPWYDhZlwTn3sePJnU9VrGMmwdXAIEyoOnrjreYlVM_Z4N13eK9-TmMTWyfKJtHQ\",\n\t\t\"ES256\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic ES384\",\n\t\tmap[string]string{\"private\": \"test/ec384-private.pem\", \"public\": \"test/ec384-public.pem\"},\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzM4NCJ9.eyJmb28iOiJiYXIifQ.ngAfKMbJUh0WWubSIYe5GMsA-aHNKwFbJk_wq3lq23aPp8H2anb1rRILIzVR0gUf4a8WzDtrzmiikuPWyCS6CN4-PwdgTk-5nehC7JXqlaBZU05p3toM3nWCwm_LXcld\",\n\t\t\"ES384\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic ES512\",\n\t\tmap[string]string{\"private\": \"test/ec512-private.pem\", \"public\": \"test/ec512-public.pem\"},\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJmb28iOiJiYXIifQ.AAU0TvGQOcdg2OvrwY73NHKgfk26UDekh9Prz-L_iWuTBIBqOFCWwwLsRiHB1JOddfKAls5do1W0jR_F30JpVd-6AJeTjGKA4C1A1H6gIKwRY0o_tFDIydZCl_lMBMeG5VNFAjO86-WCSKwc3hqaGkq1MugPRq_qrF9AVbuEB4JPLyL5\",\n\t\t\"ES512\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"basic ES256 invalid: foo => bar\",\n\t\tmap[string]string{\"private\": \"test/ec256-private.pem\", \"public\": \"test/ec256-public.pem\"},\n\t\t\"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.MEQCIHoSJnmGlPaVQDqacx_2XlXEhhqtWceVopjomc2PJLtdAiAUTeGPoNYxZw0z8mgOnnIcjoxRuNDVZvybRZF3wR1l8W\",\n\t\t\"ES256\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\tfalse,\n\t},\n}\n\nfunc TestECDSAVerify(t *testing.T) {\n\tfor _, data := range ecdsaTestData {\n\t\tvar err error\n\n\t\tkey, _ := ioutil.ReadFile(data.keys[\"public\"])\n\n\t\tvar ecdsaKey *ecdsa.PublicKey\n\t\tif ecdsaKey, err = jwt.ParseECPublicKeyFromPEM(key); err != nil {\n\t\t\tt.Errorf(\"Unable to parse ECDSA public key: %v\", err)\n\t\t}\n\n\t\tparts := strings.Split(data.tokenString, \".\")\n\n\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\terr = method.Verify(strings.Join(parts[0:2], \".\"), parts[2], ecdsaKey)\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying key: %v\", data.name, err)\n\t\t}\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid key passed validation\", data.name)\n\t\t}\n\t}\n}\n\nfunc TestECDSASign(t *testing.T) {\n\tfor _, data := range ecdsaTestData {\n\t\tvar err error\n\t\tkey, _ := ioutil.ReadFile(data.keys[\"private\"])\n\n\t\tvar ecdsaKey *ecdsa.PrivateKey\n\t\tif ecdsaKey, err = jwt.ParseECPrivateKeyFromPEM(key); err != nil {\n\t\t\tt.Errorf(\"Unable to parse ECDSA private key: %v\", err)\n\t\t}\n\n\t\tif data.valid {\n\t\t\tparts := strings.Split(data.tokenString, \".\")\n\t\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\t\tsig, err := method.Sign(strings.Join(parts[0:2], \".\"), ecdsaKey)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%v] Error signing token: %v\", data.name, err)\n\t\t\t}\n\t\t\tif sig == parts[2] {\n\t\t\t\tt.Errorf(\"[%v] Identical signatures\\nbefore:\\n%v\\nafter:\\n%v\", data.name, parts[2], sig)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ecdsa_utils.go",
    "content": "package jwt\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n)\n\nvar (\n\tErrNotECPublicKey  = errors.New(\"Key is not a valid ECDSA public key\")\n\tErrNotECPrivateKey = errors.New(\"Key is not a valid ECDSA private key\")\n)\n\n// Parse PEM encoded Elliptic Curve Private Key Structure\nfunc ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {\n\tvar err error\n\n\t// Parse PEM block\n\tvar block *pem.Block\n\tif block, _ = pem.Decode(key); block == nil {\n\t\treturn nil, ErrKeyMustBePEMEncoded\n\t}\n\n\t// Parse the key\n\tvar parsedKey interface{}\n\tif parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {\n\t\tif parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar pkey *ecdsa.PrivateKey\n\tvar ok bool\n\tif pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {\n\t\treturn nil, ErrNotECPrivateKey\n\t}\n\n\treturn pkey, nil\n}\n\n// Parse PEM encoded PKCS1 or PKCS8 public key\nfunc ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {\n\tvar err error\n\n\t// Parse PEM block\n\tvar block *pem.Block\n\tif block, _ = pem.Decode(key); block == nil {\n\t\treturn nil, ErrKeyMustBePEMEncoded\n\t}\n\n\t// Parse the key\n\tvar parsedKey interface{}\n\tif parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {\n\t\tif cert, err := x509.ParseCertificate(block.Bytes); err == nil {\n\t\t\tparsedKey = cert.PublicKey\n\t\t} else {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar pkey *ecdsa.PublicKey\n\tvar ok bool\n\tif pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok {\n\t\treturn nil, ErrNotECPublicKey\n\t}\n\n\treturn pkey, nil\n}\n"
  },
  {
    "path": "errors.go",
    "content": "package jwt\n\nimport (\n\t\"errors\"\n)\n\n// Error constants\nvar (\n\tErrInvalidKey      = errors.New(\"key is invalid\")\n\tErrInvalidKeyType  = errors.New(\"key is of invalid type\")\n\tErrHashUnavailable = errors.New(\"the requested hash function is unavailable\")\n)\n\n// The errors that might occur when parsing and validating a token\nconst (\n\tValidationErrorMalformed        uint32 = 1 << iota // Token is malformed\n\tValidationErrorUnverifiable                        // Token could not be verified because of signing problems\n\tValidationErrorSignatureInvalid                    // Signature validation failed\n\n\t// Standard Claim validation errors\n\tValidationErrorAudience      // AUD validation failed\n\tValidationErrorExpired       // EXP validation failed\n\tValidationErrorIssuedAt      // IAT validation failed\n\tValidationErrorIssuer        // ISS validation failed\n\tValidationErrorNotValidYet   // NBF validation failed\n\tValidationErrorId            // JTI validation failed\n\tValidationErrorClaimsInvalid // Generic claims validation error\n)\n\n// Helper for constructing a ValidationError with a string error message\nfunc NewValidationError(errorText string, errorFlags uint32) *ValidationError {\n\treturn &ValidationError{\n\t\ttext:   errorText,\n\t\tErrors: errorFlags,\n\t}\n}\n\n// The error from Parse if token is not valid\ntype ValidationError struct {\n\tInner  error  // stores the error returned by external dependencies, i.e.: KeyFunc\n\tErrors uint32 // bitfield.  see ValidationError... constants\n\ttext   string // errors that do not have a valid error just have text\n}\n\n// Validation error is an error type\nfunc (e ValidationError) Error() string {\n\tif e.Inner != nil {\n\t\treturn e.Inner.Error()\n\t} else if e.text != \"\" {\n\t\treturn e.text\n\t} else {\n\t\treturn \"token is invalid\"\n\t}\n}\n\n// No errors\nfunc (e *ValidationError) valid() bool {\n\treturn e.Errors == 0\n}\n"
  },
  {
    "path": "example_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"fmt\"\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"time\"\n)\n\n// Example (atypical) using the StandardClaims type by itself to parse a token.\n// The StandardClaims type is designed to be embedded into your custom types\n// to provide standard validation features.  You can use it alone, but there's\n// no way to retrieve other fields after parsing.\n// See the CustomClaimsType example for intended usage.\nfunc ExampleNewWithClaims_standardClaims() {\n\tmySigningKey := []byte(\"AllYourBase\")\n\n\t// Create the Claims\n\tclaims := &jwt.StandardClaims{\n\t\tExpiresAt: 15000,\n\t\tIssuer:    \"test\",\n\t}\n\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\tss, err := token.SignedString(mySigningKey)\n\tfmt.Printf(\"%v %v\", ss, err)\n\t//Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.QsODzZu3lUZMVdhbO76u3Jv02iYCvEHcYVUI1kOWEU0 <nil>\n}\n\n// Example creating a token using a custom claims type.  The StandardClaim is embedded\n// in the custom type to allow for easy encoding, parsing and validation of standard claims.\nfunc ExampleNewWithClaims_customClaimsType() {\n\tmySigningKey := []byte(\"AllYourBase\")\n\n\ttype MyCustomClaims struct {\n\t\tFoo string `json:\"foo\"`\n\t\tjwt.StandardClaims\n\t}\n\n\t// Create the Claims\n\tclaims := MyCustomClaims{\n\t\t\"bar\",\n\t\tjwt.StandardClaims{\n\t\t\tExpiresAt: 15000,\n\t\t\tIssuer:    \"test\",\n\t\t},\n\t}\n\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\tss, err := token.SignedString(mySigningKey)\n\tfmt.Printf(\"%v %v\", ss, err)\n\t//Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c <nil>\n}\n\n// Example creating a token using a custom claims type.  The StandardClaim is embedded\n// in the custom type to allow for easy encoding, parsing and validation of standard claims.\nfunc ExampleParseWithClaims_customClaimsType() {\n\ttokenString := \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c\"\n\n\ttype MyCustomClaims struct {\n\t\tFoo string `json:\"foo\"`\n\t\tjwt.StandardClaims\n\t}\n\n\t// sample token is expired.  override time so it parses as valid\n\tat(time.Unix(0, 0), func() {\n\t\ttoken, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {\n\t\t\treturn []byte(\"AllYourBase\"), nil\n\t\t})\n\n\t\tif claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {\n\t\t\tfmt.Printf(\"%v %v\", claims.Foo, claims.StandardClaims.ExpiresAt)\n\t\t} else {\n\t\t\tfmt.Println(err)\n\t\t}\n\t})\n\n\t// Output: bar 15000\n}\n\n// Override time value for tests.  Restore default value after.\nfunc at(t time.Time, f func()) {\n\tjwt.TimeFunc = func() time.Time {\n\t\treturn t\n\t}\n\tf()\n\tjwt.TimeFunc = time.Now\n}\n\n// An example of parsing the error types using bitfield checks\nfunc ExampleParse_errorChecking() {\n\t// Token from another example.  This token is expired\n\tvar tokenString = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c\"\n\n\ttoken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {\n\t\treturn []byte(\"AllYourBase\"), nil\n\t})\n\n\tif token.Valid {\n\t\tfmt.Println(\"You look nice today\")\n\t} else if ve, ok := err.(*jwt.ValidationError); ok {\n\t\tif ve.Errors&jwt.ValidationErrorMalformed != 0 {\n\t\t\tfmt.Println(\"That's not even a token\")\n\t\t} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {\n\t\t\t// Token is either expired or not active yet\n\t\t\tfmt.Println(\"Timing is everything\")\n\t\t} else {\n\t\t\tfmt.Println(\"Couldn't handle this token:\", err)\n\t\t}\n\t} else {\n\t\tfmt.Println(\"Couldn't handle this token:\", err)\n\t}\n\n\t// Output: Timing is everything\n}\n"
  },
  {
    "path": "hmac.go",
    "content": "package jwt\n\nimport (\n\t\"crypto\"\n\t\"crypto/hmac\"\n\t\"errors\"\n)\n\n// Implements the HMAC-SHA family of signing methods signing methods\n// Expects key type of []byte for both signing and validation\ntype SigningMethodHMAC struct {\n\tName string\n\tHash crypto.Hash\n}\n\n// Specific instances for HS256 and company\nvar (\n\tSigningMethodHS256  *SigningMethodHMAC\n\tSigningMethodHS384  *SigningMethodHMAC\n\tSigningMethodHS512  *SigningMethodHMAC\n\tErrSignatureInvalid = errors.New(\"signature is invalid\")\n)\n\nfunc init() {\n\t// HS256\n\tSigningMethodHS256 = &SigningMethodHMAC{\"HS256\", crypto.SHA256}\n\tRegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {\n\t\treturn SigningMethodHS256\n\t})\n\n\t// HS384\n\tSigningMethodHS384 = &SigningMethodHMAC{\"HS384\", crypto.SHA384}\n\tRegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {\n\t\treturn SigningMethodHS384\n\t})\n\n\t// HS512\n\tSigningMethodHS512 = &SigningMethodHMAC{\"HS512\", crypto.SHA512}\n\tRegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {\n\t\treturn SigningMethodHS512\n\t})\n}\n\nfunc (m *SigningMethodHMAC) Alg() string {\n\treturn m.Name\n}\n\n// Verify the signature of HSXXX tokens.  Returns nil if the signature is valid.\nfunc (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {\n\t// Verify the key is the right type\n\tkeyBytes, ok := key.([]byte)\n\tif !ok {\n\t\treturn ErrInvalidKeyType\n\t}\n\n\t// Decode signature, for comparison\n\tsig, err := DecodeSegment(signature)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Can we use the specified hashing method?\n\tif !m.Hash.Available() {\n\t\treturn ErrHashUnavailable\n\t}\n\n\t// This signing method is symmetric, so we validate the signature\n\t// by reproducing the signature from the signing string and key, then\n\t// comparing that against the provided signature.\n\thasher := hmac.New(m.Hash.New, keyBytes)\n\thasher.Write([]byte(signingString))\n\tif !hmac.Equal(sig, hasher.Sum(nil)) {\n\t\treturn ErrSignatureInvalid\n\t}\n\n\t// No validation errors.  Signature is good.\n\treturn nil\n}\n\n// Implements the Sign method from SigningMethod for this signing method.\n// Key must be []byte\nfunc (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {\n\tif keyBytes, ok := key.([]byte); ok {\n\t\tif !m.Hash.Available() {\n\t\t\treturn \"\", ErrHashUnavailable\n\t\t}\n\n\t\thasher := hmac.New(m.Hash.New, keyBytes)\n\t\thasher.Write([]byte(signingString))\n\n\t\treturn EncodeSegment(hasher.Sum(nil)), nil\n\t}\n\n\treturn \"\", ErrInvalidKeyType\n}\n"
  },
  {
    "path": "hmac_example_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"fmt\"\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"io/ioutil\"\n\t\"time\"\n)\n\n// For HMAC signing method, the key can be any []byte. It is recommended to generate\n// a key using crypto/rand or something equivalent. You need the same key for signing\n// and validating.\nvar hmacSampleSecret []byte\n\nfunc init() {\n\t// Load sample key data\n\tif keyData, e := ioutil.ReadFile(\"test/hmacTestKey\"); e == nil {\n\t\thmacSampleSecret = keyData\n\t} else {\n\t\tpanic(e)\n\t}\n}\n\n// Example creating, signing, and encoding a JWT token using the HMAC signing method\nfunc ExampleNew_hmac() {\n\t// Create a new token object, specifying signing method and the claims\n\t// you would like it to contain.\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{\n\t\t\"foo\": \"bar\",\n\t\t\"nbf\": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),\n\t})\n\n\t// Sign and get the complete encoded token as a string using the secret\n\ttokenString, err := token.SignedString(hmacSampleSecret)\n\n\tfmt.Println(tokenString, err)\n\t// Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58Br-Zk-bh7vLiRIsrpU <nil>\n}\n\n// Example parsing and validating a token using the HMAC signing method\nfunc ExampleParse_hmac() {\n\t// sample token string taken from the New example\n\ttokenString := \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58Br-Zk-bh7vLiRIsrpU\"\n\n\t// Parse takes the token string and a function for looking up the key. The latter is especially\n\t// useful if you use multiple keys for your application.  The standard is to use 'kid' in the\n\t// head of the token to identify which key to use, but the parsed token (head and claims) is provided\n\t// to the callback, providing flexibility.\n\ttoken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {\n\t\t// Don't forget to validate the alg is what you expect:\n\t\tif _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, fmt.Errorf(\"Unexpected signing method: %v\", token.Header[\"alg\"])\n\t\t}\n\t\t\n\t\t// hmacSampleSecret is a []byte containing your secret, e.g. []byte(\"my_secret_key\")\n\t\treturn hmacSampleSecret, nil\n\t})\n\n\tif claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {\n\t\tfmt.Println(claims[\"foo\"], claims[\"nbf\"])\n\t} else {\n\t\tfmt.Println(err)\n\t}\n\n\t// Output: bar 1.4444784e+09\n}\n"
  },
  {
    "path": "hmac_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"io/ioutil\"\n\t\"strings\"\n\t\"testing\"\n)\n\nvar hmacTestData = []struct {\n\tname        string\n\ttokenString string\n\talg         string\n\tclaims      map[string]interface{}\n\tvalid       bool\n}{\n\t{\n\t\t\"web sample\",\n\t\t\"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\",\n\t\t\"HS256\",\n\t\tmap[string]interface{}{\"iss\": \"joe\", \"exp\": 1300819380, \"http://example.com/is_root\": true},\n\t\ttrue,\n\t},\n\t{\n\t\t\"HS384\",\n\t\t\"eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.KWZEuOD5lbBxZ34g7F-SlVLAQ_r5KApWNWlZIIMyQVz5Zs58a7XdNzj5_0EcNoOy\",\n\t\t\"HS384\",\n\t\tmap[string]interface{}{\"iss\": \"joe\", \"exp\": 1300819380, \"http://example.com/is_root\": true},\n\t\ttrue,\n\t},\n\t{\n\t\t\"HS512\",\n\t\t\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.CN7YijRX6Aw1n2jyI2Id1w90ja-DEMYiWixhYCyHnrZ1VfJRaFQz1bEbjjA5Fn4CLYaUG432dEYmSbS4Saokmw\",\n\t\t\"HS512\",\n\t\tmap[string]interface{}{\"iss\": \"joe\", \"exp\": 1300819380, \"http://example.com/is_root\": true},\n\t\ttrue,\n\t},\n\t{\n\t\t\"web sample: invalid\",\n\t\t\"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXo\",\n\t\t\"HS256\",\n\t\tmap[string]interface{}{\"iss\": \"joe\", \"exp\": 1300819380, \"http://example.com/is_root\": true},\n\t\tfalse,\n\t},\n}\n\n// Sample data from http://tools.ietf.org/html/draft-jones-json-web-signature-04#appendix-A.1\nvar hmacTestKey, _ = ioutil.ReadFile(\"test/hmacTestKey\")\n\nfunc TestHMACVerify(t *testing.T) {\n\tfor _, data := range hmacTestData {\n\t\tparts := strings.Split(data.tokenString, \".\")\n\n\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\terr := method.Verify(strings.Join(parts[0:2], \".\"), parts[2], hmacTestKey)\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying key: %v\", data.name, err)\n\t\t}\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid key passed validation\", data.name)\n\t\t}\n\t}\n}\n\nfunc TestHMACSign(t *testing.T) {\n\tfor _, data := range hmacTestData {\n\t\tif data.valid {\n\t\t\tparts := strings.Split(data.tokenString, \".\")\n\t\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\t\tsig, err := method.Sign(strings.Join(parts[0:2], \".\"), hmacTestKey)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%v] Error signing token: %v\", data.name, err)\n\t\t\t}\n\t\t\tif sig != parts[2] {\n\t\t\t\tt.Errorf(\"[%v] Incorrect signature.\\nwas:\\n%v\\nexpecting:\\n%v\", data.name, sig, parts[2])\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc BenchmarkHS256Signing(b *testing.B) {\n\tbenchmarkSigning(b, jwt.SigningMethodHS256, hmacTestKey)\n}\n\nfunc BenchmarkHS384Signing(b *testing.B) {\n\tbenchmarkSigning(b, jwt.SigningMethodHS384, hmacTestKey)\n}\n\nfunc BenchmarkHS512Signing(b *testing.B) {\n\tbenchmarkSigning(b, jwt.SigningMethodHS512, hmacTestKey)\n}\n"
  },
  {
    "path": "http_example_test.go",
    "content": "package jwt_test\n\n// Example HTTP auth using asymmetric crypto/RSA keys\n// This is based on a (now outdated) example at https://gist.github.com/cryptix/45c33ecf0ae54828e63b\n\nimport (\n\t\"bytes\"\n\t\"crypto/rsa\"\n\t\"fmt\"\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"github.com/dgrijalva/jwt-go/request\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n)\n\n// location of the files used for signing and verification\nconst (\n\tprivKeyPath = \"test/sample_key\"     // openssl genrsa -out app.rsa keysize\n\tpubKeyPath  = \"test/sample_key.pub\" // openssl rsa -in app.rsa -pubout > app.rsa.pub\n)\n\nvar (\n\tverifyKey  *rsa.PublicKey\n\tsignKey    *rsa.PrivateKey\n\tserverPort int\n\t// storing sample username/password pairs\n\t// don't do this on a real server\n\tusers = map[string]string{\n\t\t\"test\": \"known\",\n\t}\n)\n\n// read the key files before starting http handlers\nfunc init() {\n\tsignBytes, err := ioutil.ReadFile(privKeyPath)\n\tfatal(err)\n\n\tsignKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)\n\tfatal(err)\n\n\tverifyBytes, err := ioutil.ReadFile(pubKeyPath)\n\tfatal(err)\n\n\tverifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)\n\tfatal(err)\n\n\thttp.HandleFunc(\"/authenticate\", authHandler)\n\thttp.HandleFunc(\"/restricted\", restrictedHandler)\n\n\t// Setup listener\n\tlistener, err := net.ListenTCP(\"tcp\", &net.TCPAddr{})\n\tserverPort = listener.Addr().(*net.TCPAddr).Port\n\n\tlog.Println(\"Listening...\")\n\tgo func() {\n\t\tfatal(http.Serve(listener, nil))\n\t}()\n}\n\nvar start func()\n\nfunc fatal(err error) {\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\n// Define some custom types were going to use within our tokens\ntype CustomerInfo struct {\n\tName string\n\tKind string\n}\n\ntype CustomClaimsExample struct {\n\t*jwt.StandardClaims\n\tTokenType string\n\tCustomerInfo\n}\n\nfunc Example_getTokenViaHTTP() {\n\t// See func authHandler for an example auth handler that produces a token\n\tres, err := http.PostForm(fmt.Sprintf(\"http://localhost:%v/authenticate\", serverPort), url.Values{\n\t\t\"user\": {\"test\"},\n\t\t\"pass\": {\"known\"},\n\t})\n\tif err != nil {\n\t\tfatal(err)\n\t}\n\n\tif res.StatusCode != 200 {\n\t\tfmt.Println(\"Unexpected status code\", res.StatusCode)\n\t}\n\n\t// Read the token out of the response body\n\tbuf := new(bytes.Buffer)\n\tio.Copy(buf, res.Body)\n\tres.Body.Close()\n\ttokenString := strings.TrimSpace(buf.String())\n\n\t// Parse the token\n\ttoken, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {\n\t\t// since we only use the one private key to sign the tokens,\n\t\t// we also only use its public counter part to verify\n\t\treturn verifyKey, nil\n\t})\n\tfatal(err)\n\n\tclaims := token.Claims.(*CustomClaimsExample)\n\tfmt.Println(claims.CustomerInfo.Name)\n\n\t//Output: test\n}\n\nfunc Example_useTokenViaHTTP() {\n\n\t// Make a sample token\n\t// In a real world situation, this token will have been acquired from\n\t// some other API call (see Example_getTokenViaHTTP)\n\ttoken, err := createToken(\"foo\")\n\tfatal(err)\n\n\t// Make request.  See func restrictedHandler for example request processor\n\treq, err := http.NewRequest(\"GET\", fmt.Sprintf(\"http://localhost:%v/restricted\", serverPort), nil)\n\tfatal(err)\n\treq.Header.Set(\"Authorization\", fmt.Sprintf(\"Bearer %v\", token))\n\tres, err := http.DefaultClient.Do(req)\n\tfatal(err)\n\n\t// Read the response body\n\tbuf := new(bytes.Buffer)\n\tio.Copy(buf, res.Body)\n\tres.Body.Close()\n\tfmt.Println(buf.String())\n\n\t// Output: Welcome, foo\n}\n\nfunc createToken(user string) (string, error) {\n\t// create a signer for rsa 256\n\tt := jwt.New(jwt.GetSigningMethod(\"RS256\"))\n\n\t// set our claims\n\tt.Claims = &CustomClaimsExample{\n\t\t&jwt.StandardClaims{\n\t\t\t// set the expire time\n\t\t\t// see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4\n\t\t\tExpiresAt: time.Now().Add(time.Minute * 1).Unix(),\n\t\t},\n\t\t\"level1\",\n\t\tCustomerInfo{user, \"human\"},\n\t}\n\n\t// Creat token string\n\treturn t.SignedString(signKey)\n}\n\n// reads the form values, checks them and creates the token\nfunc authHandler(w http.ResponseWriter, r *http.Request) {\n\t// make sure its post\n\tif r.Method != \"POST\" {\n\t\tw.WriteHeader(http.StatusBadRequest)\n\t\tfmt.Fprintln(w, \"No POST\", r.Method)\n\t\treturn\n\t}\n\n\tuser := r.FormValue(\"user\")\n\tpass := r.FormValue(\"pass\")\n\n\tlog.Printf(\"Authenticate: user[%s] pass[%s]\\n\", user, pass)\n\n\t// check values\n\tif user != \"test\" || pass != \"known\" {\n\t\tw.WriteHeader(http.StatusForbidden)\n\t\tfmt.Fprintln(w, \"Wrong info\")\n\t\treturn\n\t}\n\n\ttokenString, err := createToken(user)\n\tif err != nil {\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\tfmt.Fprintln(w, \"Sorry, error while Signing Token!\")\n\t\tlog.Printf(\"Token Signing error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/jwt\")\n\tw.WriteHeader(http.StatusOK)\n\tfmt.Fprintln(w, tokenString)\n}\n\n// only accessible with a valid token\nfunc restrictedHandler(w http.ResponseWriter, r *http.Request) {\n\t// Get token from request\n\ttoken, err := request.ParseFromRequestWithClaims(r, request.OAuth2Extractor, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {\n\t\t// since we only use the one private key to sign the tokens,\n\t\t// we also only use its public counter part to verify\n\t\treturn verifyKey, nil\n\t})\n\n\t// If the token is missing or invalid, return error\n\tif err != nil {\n\t\tw.WriteHeader(http.StatusUnauthorized)\n\t\tfmt.Fprintln(w, \"Invalid token:\", err)\n\t\treturn\n\t}\n\n\t// Token is valid\n\tfmt.Fprintln(w, \"Welcome,\", token.Claims.(*CustomClaimsExample).Name)\n\treturn\n}\n"
  },
  {
    "path": "map_claims.go",
    "content": "package jwt\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t// \"fmt\"\n)\n\n// Claims type that uses the map[string]interface{} for JSON decoding\n// This is the default claims type if you don't supply one\ntype MapClaims map[string]interface{}\n\n// VerifyAudience Compares the aud claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (m MapClaims) VerifyAudience(cmp string, req bool) bool {\n\tvar aud []string\n\tswitch v := m[\"aud\"].(type) {\n\tcase string:\n\t\taud = append(aud, v)\n\tcase []string:\n\t\taud = v\n\tcase []interface{}:\n\t\tfor _, a := range v {\n\t\t\tvs, ok := a.(string)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\taud = append(aud, vs)\n\t\t}\n\t}\n\treturn verifyAud(aud, cmp, req)\n}\n\n// Compares the exp claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {\n\tswitch exp := m[\"exp\"].(type) {\n\tcase float64:\n\t\treturn verifyExp(int64(exp), cmp, req)\n\tcase json.Number:\n\t\tv, _ := exp.Int64()\n\t\treturn verifyExp(v, cmp, req)\n\t}\n\treturn req == false\n}\n\n// Compares the iat claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {\n\tswitch iat := m[\"iat\"].(type) {\n\tcase float64:\n\t\treturn verifyIat(int64(iat), cmp, req)\n\tcase json.Number:\n\t\tv, _ := iat.Int64()\n\t\treturn verifyIat(v, cmp, req)\n\t}\n\treturn req == false\n}\n\n// Compares the iss claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (m MapClaims) VerifyIssuer(cmp string, req bool) bool {\n\tiss, _ := m[\"iss\"].(string)\n\treturn verifyIss(iss, cmp, req)\n}\n\n// Compares the nbf claim against cmp.\n// If required is false, this method will return true if the value matches or is unset\nfunc (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {\n\tswitch nbf := m[\"nbf\"].(type) {\n\tcase float64:\n\t\treturn verifyNbf(int64(nbf), cmp, req)\n\tcase json.Number:\n\t\tv, _ := nbf.Int64()\n\t\treturn verifyNbf(v, cmp, req)\n\t}\n\treturn req == false\n}\n\n// Validates time based claims \"exp, iat, nbf\".\n// There is no accounting for clock skew.\n// As well, if any of the above claims are not in the token, it will still\n// be considered a valid claim.\nfunc (m MapClaims) Valid() error {\n\tvErr := new(ValidationError)\n\tnow := TimeFunc().Unix()\n\n\tif m.VerifyExpiresAt(now, false) == false {\n\t\tvErr.Inner = errors.New(\"Token is expired\")\n\t\tvErr.Errors |= ValidationErrorExpired\n\t}\n\n\tif m.VerifyIssuedAt(now, false) == false {\n\t\tvErr.Inner = errors.New(\"Token used before issued\")\n\t\tvErr.Errors |= ValidationErrorIssuedAt\n\t}\n\n\tif m.VerifyNotBefore(now, false) == false {\n\t\tvErr.Inner = errors.New(\"Token is not valid yet\")\n\t\tvErr.Errors |= ValidationErrorNotValidYet\n\t}\n\n\tif vErr.valid() {\n\t\treturn nil\n\t}\n\n\treturn vErr\n}\n"
  },
  {
    "path": "map_claims_test.go",
    "content": "package jwt\n\nimport (\n\t\"testing\"\n)\n\nfunc TestVerifyAud(t *testing.T) {\n\tvar nilInterface interface{}\n\tvar nilListInterface []interface{}\n\tvar intListInterface interface{} = []int{1,2,3}\n\ttype test struct{\n\t\tName string\n\t\tMapClaims MapClaims\n\t\tExpected bool\n\t\tComparison string\n\t\tRequired bool\n\t}\n\ttests := []test{\n\t\t// Matching Claim in aud\n\t\t// Required = true\n\t\t{ Name: \"String Aud matching required\", MapClaims: MapClaims{\"aud\": \"example.com\"}, Expected: true , Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"[]String Aud with match required\", MapClaims: MapClaims{\"aud\": []string{\"example.com\", \"example.example.com\"}}, Expected: true, Required: true, Comparison: \"example.com\"},\n\n\t\t// Required = false\n\t\t{ Name: \"String Aud with match not required\", MapClaims: MapClaims{\"aud\": \"example.com\"}, Expected: true , Required: false, Comparison: \"example.com\"},\n\t\t{ Name: \"Empty String Aud with match not required\", MapClaims: MapClaims{}, Expected: true , Required: false, Comparison: \"example.com\"},\n\t\t{ Name: \"Empty String Aud with match not required\", MapClaims: MapClaims{\"aud\": \"\"}, Expected: true , Required: false, Comparison: \"example.com\"},\n\t\t{ Name: \"Nil String Aud with match not required\", MapClaims: MapClaims{\"aud\": nil}, Expected: true , Required: false, Comparison: \"example.com\"},\n\n\t\t{ Name: \"[]String Aud with match not required\", MapClaims: MapClaims{\"aud\": []string{\"example.com\", \"example.example.com\"}}, Expected: true, Required: false, Comparison: \"example.com\"},\n\t\t{ Name: \"Empty []String Aud with match not required\", MapClaims: MapClaims{\"aud\": []string{}}, Expected: true, Required: false, Comparison: \"example.com\"},\n\n\t\t// Non-Matching Claim in aud\n\t\t// Required = true\n\t\t{ Name: \"String Aud without match required\", MapClaims: MapClaims{\"aud\": \"not.example.com\"}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"Empty String Aud without match required\", MapClaims: MapClaims{\"aud\": \"\"}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"[]String Aud without match required\", MapClaims: MapClaims{\"aud\": []string{\"not.example.com\", \"example.example.com\"}}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"Empty []String Aud without match required\", MapClaims: MapClaims{\"aud\": []string{\"\"}}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"String Aud without match not required\", MapClaims: MapClaims{\"aud\": \"not.example.com\"}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"Empty String Aud without match not required\", MapClaims: MapClaims{\"aud\": \"\"}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"[]String Aud without match not required\", MapClaims: MapClaims{\"aud\": []string{\"not.example.com\", \"example.example.com\"}}, Expected: false, Required: true, Comparison: \"example.com\"},\n\n\t\t// Required = false\n\t\t{ Name: \"Empty []String Aud without match required\", MapClaims: MapClaims{\"aud\": []string{\"\"}}, Expected: false, Required: true, Comparison: \"example.com\"},\n\n\t\t// []interface{}\n\t\t{ Name: \"Empty []interface{} Aud without match required\", MapClaims: MapClaims{\"aud\": nilListInterface}, Expected: true, Required: false, Comparison: \"example.com\"},\n\t\t{ Name: \"[]interface{} Aud wit match required\", MapClaims: MapClaims{\"aud\": []interface{}{\"a\", \"foo\", \"example.com\"}}, Expected: true, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"[]interface{} Aud wit match but invalid types\", MapClaims: MapClaims{\"aud\": []interface{}{\"a\", 5, \"example.com\"}}, Expected: false, Required: true, Comparison: \"example.com\"},\n\t\t{ Name: \"[]interface{} Aud int wit match required\", MapClaims: MapClaims{\"aud\": intListInterface}, Expected: false, Required: true, Comparison: \"example.com\"},\n\n\n\t\t// interface{}\n\t\t{ Name: \"Empty interface{} Aud without match not required\", MapClaims: MapClaims{\"aud\": nilInterface}, Expected: true, Required: false, Comparison: \"example.com\"},\n\n\t}\n\n\n\tfor _, test := range tests {\n\t\tt.Run(test.Name, func(t *testing.T) {\n\t\t\tgot := test.MapClaims.VerifyAudience(test.Comparison, test.Required)\n\n\t\t\tif got != test.Expected {\n\t\t\t\tt.Errorf(\"Expected %v, got %v\", test.Expected, got)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "none.go",
    "content": "package jwt\n\n// Implements the none signing method.  This is required by the spec\n// but you probably should never use it.\nvar SigningMethodNone *signingMethodNone\n\nconst UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = \"none signing method allowed\"\n\nvar NoneSignatureTypeDisallowedError error\n\ntype signingMethodNone struct{}\ntype unsafeNoneMagicConstant string\n\nfunc init() {\n\tSigningMethodNone = &signingMethodNone{}\n\tNoneSignatureTypeDisallowedError = NewValidationError(\"'none' signature type is not allowed\", ValidationErrorSignatureInvalid)\n\n\tRegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod {\n\t\treturn SigningMethodNone\n\t})\n}\n\nfunc (m *signingMethodNone) Alg() string {\n\treturn \"none\"\n}\n\n// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key\nfunc (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) {\n\t// Key must be UnsafeAllowNoneSignatureType to prevent accidentally\n\t// accepting 'none' signing method\n\tif _, ok := key.(unsafeNoneMagicConstant); !ok {\n\t\treturn NoneSignatureTypeDisallowedError\n\t}\n\t// If signing method is none, signature must be an empty string\n\tif signature != \"\" {\n\t\treturn NewValidationError(\n\t\t\t\"'none' signing method with non-empty signature\",\n\t\t\tValidationErrorSignatureInvalid,\n\t\t)\n\t}\n\n\t// Accept 'none' signing method.\n\treturn nil\n}\n\n// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key\nfunc (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) {\n\tif _, ok := key.(unsafeNoneMagicConstant); ok {\n\t\treturn \"\", nil\n\t}\n\treturn \"\", NoneSignatureTypeDisallowedError\n}\n"
  },
  {
    "path": "none_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"strings\"\n\t\"testing\"\n)\n\nvar noneTestData = []struct {\n\tname        string\n\ttokenString string\n\talg         string\n\tkey         interface{}\n\tclaims      map[string]interface{}\n\tvalid       bool\n}{\n\t{\n\t\t\"Basic\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.\",\n\t\t\"none\",\n\t\tjwt.UnsafeAllowNoneSignatureType,\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic - no key\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.\",\n\t\t\"none\",\n\t\tnil,\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\tfalse,\n\t},\n\t{\n\t\t\"Signed\",\n\t\t\"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw\",\n\t\t\"none\",\n\t\tjwt.UnsafeAllowNoneSignatureType,\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\tfalse,\n\t},\n}\n\nfunc TestNoneVerify(t *testing.T) {\n\tfor _, data := range noneTestData {\n\t\tparts := strings.Split(data.tokenString, \".\")\n\n\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\terr := method.Verify(strings.Join(parts[0:2], \".\"), parts[2], data.key)\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying key: %v\", data.name, err)\n\t\t}\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid key passed validation\", data.name)\n\t\t}\n\t}\n}\n\nfunc TestNoneSign(t *testing.T) {\n\tfor _, data := range noneTestData {\n\t\tif data.valid {\n\t\t\tparts := strings.Split(data.tokenString, \".\")\n\t\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\t\tsig, err := method.Sign(strings.Join(parts[0:2], \".\"), data.key)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%v] Error signing token: %v\", data.name, err)\n\t\t\t}\n\t\t\tif sig != parts[2] {\n\t\t\t\tt.Errorf(\"[%v] Incorrect signature.\\nwas:\\n%v\\nexpecting:\\n%v\", data.name, sig, parts[2])\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "parser.go",
    "content": "package jwt\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype Parser struct {\n\tValidMethods         []string // If populated, only these methods will be considered valid\n\tUseJSONNumber        bool     // Use JSON Number format in JSON decoder\n\tSkipClaimsValidation bool     // Skip claims validation during token parsing\n}\n\n// Parse, validate, and return a token.\n// keyFunc will receive the parsed token and should return the key for validating.\n// If everything is kosher, err will be nil\nfunc (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {\n\treturn p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)\n}\n\nfunc (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {\n\ttoken, parts, err := p.ParseUnverified(tokenString, claims)\n\tif err != nil {\n\t\treturn token, err\n\t}\n\n\t// Verify signing method is in the required set\n\tif p.ValidMethods != nil {\n\t\tvar signingMethodValid = false\n\t\tvar alg = token.Method.Alg()\n\t\tfor _, m := range p.ValidMethods {\n\t\t\tif m == alg {\n\t\t\t\tsigningMethodValid = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !signingMethodValid {\n\t\t\t// signing method is not in the listed set\n\t\t\treturn token, NewValidationError(fmt.Sprintf(\"signing method %v is invalid\", alg), ValidationErrorSignatureInvalid)\n\t\t}\n\t}\n\n\t// Lookup key\n\tvar key interface{}\n\tif keyFunc == nil {\n\t\t// keyFunc was not provided.  short circuiting validation\n\t\treturn token, NewValidationError(\"no Keyfunc was provided.\", ValidationErrorUnverifiable)\n\t}\n\tif key, err = keyFunc(token); err != nil {\n\t\t// keyFunc returned an error\n\t\tif ve, ok := err.(*ValidationError); ok {\n\t\t\treturn token, ve\n\t\t}\n\t\treturn token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}\n\t}\n\n\tvErr := &ValidationError{}\n\n\t// Validate Claims\n\tif !p.SkipClaimsValidation {\n\t\tif err := token.Claims.Valid(); err != nil {\n\n\t\t\t// If the Claims Valid returned an error, check if it is a validation error,\n\t\t\t// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set\n\t\t\tif e, ok := err.(*ValidationError); !ok {\n\t\t\t\tvErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}\n\t\t\t} else {\n\t\t\t\tvErr = e\n\t\t\t}\n\t\t}\n\t}\n\n\t// Perform validation\n\ttoken.Signature = parts[2]\n\tif err = token.Method.Verify(strings.Join(parts[0:2], \".\"), token.Signature, key); err != nil {\n\t\tvErr.Inner = err\n\t\tvErr.Errors |= ValidationErrorSignatureInvalid\n\t}\n\n\tif vErr.valid() {\n\t\ttoken.Valid = true\n\t\treturn token, nil\n\t}\n\n\treturn token, vErr\n}\n\n// WARNING: Don't use this method unless you know what you're doing\n//\n// This method parses the token but doesn't validate the signature. It's only\n// ever useful in cases where you know the signature is valid (because it has\n// been checked previously in the stack) and you want to extract values from\n// it.\nfunc (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {\n\tparts = strings.Split(tokenString, \".\")\n\tif len(parts) != 3 {\n\t\treturn nil, parts, NewValidationError(\"token contains an invalid number of segments\", ValidationErrorMalformed)\n\t}\n\n\ttoken = &Token{Raw: tokenString}\n\n\t// parse Header\n\tvar headerBytes []byte\n\tif headerBytes, err = DecodeSegment(parts[0]); err != nil {\n\t\tif strings.HasPrefix(strings.ToLower(tokenString), \"bearer \") {\n\t\t\treturn token, parts, NewValidationError(\"tokenstring should not contain 'bearer '\", ValidationErrorMalformed)\n\t\t}\n\t\treturn token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}\n\t}\n\tif err = json.Unmarshal(headerBytes, &token.Header); err != nil {\n\t\treturn token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}\n\t}\n\n\t// parse Claims\n\tvar claimBytes []byte\n\ttoken.Claims = claims\n\n\tif claimBytes, err = DecodeSegment(parts[1]); err != nil {\n\t\treturn token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}\n\t}\n\tdec := json.NewDecoder(bytes.NewBuffer(claimBytes))\n\tif p.UseJSONNumber {\n\t\tdec.UseNumber()\n\t}\n\t// JSON Decode.  Special case for map type to avoid weird pointer behavior\n\tif c, ok := token.Claims.(MapClaims); ok {\n\t\terr = dec.Decode(&c)\n\t} else {\n\t\terr = dec.Decode(&claims)\n\t}\n\t// Handle decode error\n\tif err != nil {\n\t\treturn token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}\n\t}\n\n\t// Lookup signature method\n\tif method, ok := token.Header[\"alg\"].(string); ok {\n\t\tif token.Method = GetSigningMethod(method); token.Method == nil {\n\t\t\treturn token, parts, NewValidationError(\"signing method (alg) is unavailable.\", ValidationErrorUnverifiable)\n\t\t}\n\t} else {\n\t\treturn token, parts, NewValidationError(\"signing method (alg) is unspecified.\", ValidationErrorUnverifiable)\n\t}\n\n\treturn token, parts, nil\n}\n"
  },
  {
    "path": "parser_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"crypto/rsa\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"github.com/dgrijalva/jwt-go/test\"\n)\n\nvar keyFuncError error = fmt.Errorf(\"error loading key\")\n\nvar (\n\tjwtTestDefaultKey *rsa.PublicKey\n\tdefaultKeyFunc    jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil }\n\temptyKeyFunc      jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil }\n\terrorKeyFunc      jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, keyFuncError }\n\tnilKeyFunc        jwt.Keyfunc = nil\n)\n\nfunc init() {\n\tjwtTestDefaultKey = test.LoadRSAPublicKeyFromDisk(\"test/sample_key.pub\")\n}\n\nvar jwtTestData = []struct {\n\tname        string\n\ttokenString string\n\tkeyfunc     jwt.Keyfunc\n\tclaims      jwt.Claims\n\tvalid       bool\n\terrors      uint32\n\tparser      *jwt.Parser\n}{\n\t{\n\t\t\"basic\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\ttrue,\n\t\t0,\n\t\tnil,\n\t},\n\t{\n\t\t\"basic expired\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"exp\": float64(time.Now().Unix() - 100)},\n\t\tfalse,\n\t\tjwt.ValidationErrorExpired,\n\t\tnil,\n\t},\n\t{\n\t\t\"basic nbf\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"nbf\": float64(time.Now().Unix() + 100)},\n\t\tfalse,\n\t\tjwt.ValidationErrorNotValidYet,\n\t\tnil,\n\t},\n\t{\n\t\t\"expired and nbf\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"nbf\": float64(time.Now().Unix() + 100), \"exp\": float64(time.Now().Unix() - 100)},\n\t\tfalse,\n\t\tjwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired,\n\t\tnil,\n\t},\n\t{\n\t\t\"basic invalid\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tfalse,\n\t\tjwt.ValidationErrorSignatureInvalid,\n\t\tnil,\n\t},\n\t{\n\t\t\"basic nokeyfunc\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\tnilKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tfalse,\n\t\tjwt.ValidationErrorUnverifiable,\n\t\tnil,\n\t},\n\t{\n\t\t\"basic nokey\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\temptyKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tfalse,\n\t\tjwt.ValidationErrorSignatureInvalid,\n\t\tnil,\n\t},\n\t{\n\t\t\"basic errorkey\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\terrorKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tfalse,\n\t\tjwt.ValidationErrorUnverifiable,\n\t\tnil,\n\t},\n\t{\n\t\t\"invalid signing method\",\n\t\t\"\",\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tfalse,\n\t\tjwt.ValidationErrorSignatureInvalid,\n\t\t&jwt.Parser{ValidMethods: []string{\"HS256\"}},\n\t},\n\t{\n\t\t\"valid signing method\",\n\t\t\"\",\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\ttrue,\n\t\t0,\n\t\t&jwt.Parser{ValidMethods: []string{\"RS256\", \"HS256\"}},\n\t},\n\t{\n\t\t\"JSON Number\",\n\t\t\"\",\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": json.Number(\"123.4\")},\n\t\ttrue,\n\t\t0,\n\t\t&jwt.Parser{UseJSONNumber: true},\n\t},\n\t{\n\t\t\"Standard Claims\",\n\t\t\"\",\n\t\tdefaultKeyFunc,\n\t\t&jwt.StandardClaims{\n\t\t\tExpiresAt: time.Now().Add(time.Second * 10).Unix(),\n\t\t},\n\t\ttrue,\n\t\t0,\n\t\t&jwt.Parser{UseJSONNumber: true},\n\t},\n\t{\n\t\t\"JSON Number - basic expired\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"exp\": json.Number(fmt.Sprintf(\"%v\", time.Now().Unix()-100))},\n\t\tfalse,\n\t\tjwt.ValidationErrorExpired,\n\t\t&jwt.Parser{UseJSONNumber: true},\n\t},\n\t{\n\t\t\"JSON Number - basic nbf\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"nbf\": json.Number(fmt.Sprintf(\"%v\", time.Now().Unix()+100))},\n\t\tfalse,\n\t\tjwt.ValidationErrorNotValidYet,\n\t\t&jwt.Parser{UseJSONNumber: true},\n\t},\n\t{\n\t\t\"JSON Number - expired and nbf\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"nbf\": json.Number(fmt.Sprintf(\"%v\", time.Now().Unix()+100)), \"exp\": json.Number(fmt.Sprintf(\"%v\", time.Now().Unix()-100))},\n\t\tfalse,\n\t\tjwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired,\n\t\t&jwt.Parser{UseJSONNumber: true},\n\t},\n\t{\n\t\t\"SkipClaimsValidation during token parsing\",\n\t\t\"\", // autogen\n\t\tdefaultKeyFunc,\n\t\tjwt.MapClaims{\"foo\": \"bar\", \"nbf\": json.Number(fmt.Sprintf(\"%v\", time.Now().Unix()+100))},\n\t\ttrue,\n\t\t0,\n\t\t&jwt.Parser{UseJSONNumber: true, SkipClaimsValidation: true},\n\t},\n}\n\nfunc TestParser_Parse(t *testing.T) {\n\tprivateKey := test.LoadRSAPrivateKeyFromDisk(\"test/sample_key\")\n\n\t// Iterate over test data set and run tests\n\tfor _, data := range jwtTestData {\n\t\t// If the token string is blank, use helper function to generate string\n\t\tif data.tokenString == \"\" {\n\t\t\tdata.tokenString = test.MakeSampleToken(data.claims, privateKey)\n\t\t}\n\n\t\t// Parse the token\n\t\tvar token *jwt.Token\n\t\tvar err error\n\t\tvar parser = data.parser\n\t\tif parser == nil {\n\t\t\tparser = new(jwt.Parser)\n\t\t}\n\t\t// Figure out correct claims type\n\t\tswitch data.claims.(type) {\n\t\tcase jwt.MapClaims:\n\t\t\ttoken, err = parser.ParseWithClaims(data.tokenString, jwt.MapClaims{}, data.keyfunc)\n\t\tcase *jwt.StandardClaims:\n\t\t\ttoken, err = parser.ParseWithClaims(data.tokenString, &jwt.StandardClaims{}, data.keyfunc)\n\t\t}\n\n\t\t// Verify result matches expectation\n\t\tif !reflect.DeepEqual(data.claims, token.Claims) {\n\t\t\tt.Errorf(\"[%v] Claims mismatch. Expecting: %v  Got: %v\", data.name, data.claims, token.Claims)\n\t\t}\n\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying token: %T:%v\", data.name, err, err)\n\t\t}\n\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid token passed validation\", data.name)\n\t\t}\n\n\t\tif (err == nil && !token.Valid) || (err != nil && token.Valid) {\n\t\t\tt.Errorf(\"[%v] Inconsistent behavior between returned error and token.Valid\", data.name)\n\t\t}\n\n\t\tif data.errors != 0 {\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"[%v] Expecting error.  Didn't get one.\", data.name)\n\t\t\t} else {\n\n\t\t\t\tve := err.(*jwt.ValidationError)\n\t\t\t\t// compare the bitfield part of the error\n\t\t\t\tif e := ve.Errors; e != data.errors {\n\t\t\t\t\tt.Errorf(\"[%v] Errors don't match expectation.  %v != %v\", data.name, e, data.errors)\n\t\t\t\t}\n\n\t\t\t\tif err.Error() == keyFuncError.Error() && ve.Inner != keyFuncError {\n\t\t\t\t\tt.Errorf(\"[%v] Inner error does not match expectation.  %v != %v\", data.name, ve.Inner, keyFuncError)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif data.valid && token.Signature == \"\" {\n\t\t\tt.Errorf(\"[%v] Signature is left unpopulated after parsing\", data.name)\n\t\t}\n\t}\n}\n\nfunc TestParser_ParseUnverified(t *testing.T) {\n\tprivateKey := test.LoadRSAPrivateKeyFromDisk(\"test/sample_key\")\n\n\t// Iterate over test data set and run tests\n\tfor _, data := range jwtTestData {\n\t\t// If the token string is blank, use helper function to generate string\n\t\tif data.tokenString == \"\" {\n\t\t\tdata.tokenString = test.MakeSampleToken(data.claims, privateKey)\n\t\t}\n\n\t\t// Parse the token\n\t\tvar token *jwt.Token\n\t\tvar err error\n\t\tvar parser = data.parser\n\t\tif parser == nil {\n\t\t\tparser = new(jwt.Parser)\n\t\t}\n\t\t// Figure out correct claims type\n\t\tswitch data.claims.(type) {\n\t\tcase jwt.MapClaims:\n\t\t\ttoken, _, err = parser.ParseUnverified(data.tokenString, jwt.MapClaims{})\n\t\tcase *jwt.StandardClaims:\n\t\t\ttoken, _, err = parser.ParseUnverified(data.tokenString, &jwt.StandardClaims{})\n\t\t}\n\n\t\tif err != nil {\n\t\t\tt.Errorf(\"[%v] Invalid token\", data.name)\n\t\t}\n\n\t\t// Verify result matches expectation\n\t\tif !reflect.DeepEqual(data.claims, token.Claims) {\n\t\t\tt.Errorf(\"[%v] Claims mismatch. Expecting: %v  Got: %v\", data.name, data.claims, token.Claims)\n\t\t}\n\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying token: %T:%v\", data.name, err, err)\n\t\t}\n\t}\n}\n\n// Helper method for benchmarking various methods\nfunc benchmarkSigning(b *testing.B, method jwt.SigningMethod, key interface{}) {\n\tt := jwt.New(method)\n\tb.RunParallel(func(pb *testing.PB) {\n\t\tfor pb.Next() {\n\t\t\tif _, err := t.SignedString(key); err != nil {\n\t\t\t\tb.Fatal(err)\n\t\t\t}\n\t\t}\n\t})\n\n}\n"
  },
  {
    "path": "request/doc.go",
    "content": "// Utility package for extracting JWT tokens from\n// HTTP requests.\n//\n// The main function is ParseFromRequest and it's WithClaims variant.\n// See examples for how to use the various Extractor implementations\n// or roll your own.\npackage request\n"
  },
  {
    "path": "request/extractor.go",
    "content": "package request\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n)\n\n// Errors\nvar (\n\tErrNoTokenInRequest = errors.New(\"no token present in request\")\n)\n\n// Interface for extracting a token from an HTTP request.\n// The ExtractToken method should return a token string or an error.\n// If no token is present, you must return ErrNoTokenInRequest.\ntype Extractor interface {\n\tExtractToken(*http.Request) (string, error)\n}\n\n// Extractor for finding a token in a header.  Looks at each specified\n// header in order until there's a match\ntype HeaderExtractor []string\n\nfunc (e HeaderExtractor) ExtractToken(req *http.Request) (string, error) {\n\t// loop over header names and return the first one that contains data\n\tfor _, header := range e {\n\t\tif ah := req.Header.Get(header); ah != \"\" {\n\t\t\treturn ah, nil\n\t\t}\n\t}\n\treturn \"\", ErrNoTokenInRequest\n}\n\n// Extract token from request arguments.  This includes a POSTed form or\n// GET URL arguments.  Argument names are tried in order until there's a match.\n// This extractor calls `ParseMultipartForm` on the request\ntype ArgumentExtractor []string\n\nfunc (e ArgumentExtractor) ExtractToken(req *http.Request) (string, error) {\n\t// Make sure form is parsed\n\treq.ParseMultipartForm(10e6)\n\n\t// loop over arg names and return the first one that contains data\n\tfor _, arg := range e {\n\t\tif ah := req.Form.Get(arg); ah != \"\" {\n\t\t\treturn ah, nil\n\t\t}\n\t}\n\n\treturn \"\", ErrNoTokenInRequest\n}\n\n// Tries Extractors in order until one returns a token string or an error occurs\ntype MultiExtractor []Extractor\n\nfunc (e MultiExtractor) ExtractToken(req *http.Request) (string, error) {\n\t// loop over header names and return the first one that contains data\n\tfor _, extractor := range e {\n\t\tif tok, err := extractor.ExtractToken(req); tok != \"\" {\n\t\t\treturn tok, nil\n\t\t} else if err != ErrNoTokenInRequest {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\treturn \"\", ErrNoTokenInRequest\n}\n\n// Wrap an Extractor in this to post-process the value before it's handed off.\n// See AuthorizationHeaderExtractor for an example\ntype PostExtractionFilter struct {\n\tExtractor\n\tFilter func(string) (string, error)\n}\n\nfunc (e *PostExtractionFilter) ExtractToken(req *http.Request) (string, error) {\n\tif tok, err := e.Extractor.ExtractToken(req); tok != \"\" {\n\t\treturn e.Filter(tok)\n\t} else {\n\t\treturn \"\", err\n\t}\n}\n"
  },
  {
    "path": "request/extractor_example_test.go",
    "content": "package request\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n)\n\nconst (\n\texampleTokenA = \"A\"\n)\n\nfunc ExampleHeaderExtractor() {\n\treq := makeExampleRequest(\"GET\", \"/\", map[string]string{\"Token\": exampleTokenA}, nil)\n\ttokenString, err := HeaderExtractor{\"Token\"}.ExtractToken(req)\n\tif err == nil {\n\t\tfmt.Println(tokenString)\n\t} else {\n\t\tfmt.Println(err)\n\t}\n\t//Output: A\n}\n\nfunc ExampleArgumentExtractor() {\n\treq := makeExampleRequest(\"GET\", \"/\", nil, url.Values{\"token\": {extractorTestTokenA}})\n\ttokenString, err := ArgumentExtractor{\"token\"}.ExtractToken(req)\n\tif err == nil {\n\t\tfmt.Println(tokenString)\n\t} else {\n\t\tfmt.Println(err)\n\t}\n\t//Output: A\n}\n"
  },
  {
    "path": "request/extractor_test.go",
    "content": "package request\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n)\n\nvar extractorTestTokenA = \"A\"\nvar extractorTestTokenB = \"B\"\n\nvar extractorTestData = []struct {\n\tname      string\n\textractor Extractor\n\theaders   map[string]string\n\tquery     url.Values\n\ttoken     string\n\terr       error\n}{\n\t{\n\t\tname:      \"simple header\",\n\t\textractor: HeaderExtractor{\"Foo\"},\n\t\theaders:   map[string]string{\"Foo\": extractorTestTokenA},\n\t\tquery:     nil,\n\t\ttoken:     extractorTestTokenA,\n\t\terr:       nil,\n\t},\n\t{\n\t\tname:      \"simple argument\",\n\t\textractor: ArgumentExtractor{\"token\"},\n\t\theaders:   map[string]string{},\n\t\tquery:     url.Values{\"token\": {extractorTestTokenA}},\n\t\ttoken:     extractorTestTokenA,\n\t\terr:       nil,\n\t},\n\t{\n\t\tname: \"multiple extractors\",\n\t\textractor: MultiExtractor{\n\t\t\tHeaderExtractor{\"Foo\"},\n\t\t\tArgumentExtractor{\"token\"},\n\t\t},\n\t\theaders: map[string]string{\"Foo\": extractorTestTokenA},\n\t\tquery:   url.Values{\"token\": {extractorTestTokenB}},\n\t\ttoken:   extractorTestTokenA,\n\t\terr:     nil,\n\t},\n\t{\n\t\tname:      \"simple miss\",\n\t\textractor: HeaderExtractor{\"This-Header-Is-Not-Set\"},\n\t\theaders:   map[string]string{\"Foo\": extractorTestTokenA},\n\t\tquery:     nil,\n\t\ttoken:     \"\",\n\t\terr:       ErrNoTokenInRequest,\n\t},\n\t{\n\t\tname:      \"filter\",\n\t\textractor: AuthorizationHeaderExtractor,\n\t\theaders:   map[string]string{\"Authorization\": \"Bearer \" + extractorTestTokenA},\n\t\tquery:     nil,\n\t\ttoken:     extractorTestTokenA,\n\t\terr:       nil,\n\t},\n}\n\nfunc TestExtractor(t *testing.T) {\n\t// Bearer token request\n\tfor _, data := range extractorTestData {\n\t\t// Make request from test struct\n\t\tr := makeExampleRequest(\"GET\", \"/\", data.headers, data.query)\n\n\t\t// Test extractor\n\t\ttoken, err := data.extractor.ExtractToken(r)\n\t\tif token != data.token {\n\t\t\tt.Errorf(\"[%v] Expected token '%v'.  Got '%v'\", data.name, data.token, token)\n\t\t\tcontinue\n\t\t}\n\t\tif err != data.err {\n\t\t\tt.Errorf(\"[%v] Expected error '%v'.  Got '%v'\", data.name, data.err, err)\n\t\t\tcontinue\n\t\t}\n\t}\n}\n\nfunc makeExampleRequest(method, path string, headers map[string]string, urlArgs url.Values) *http.Request {\n\tr, _ := http.NewRequest(method, fmt.Sprintf(\"%v?%v\", path, urlArgs.Encode()), nil)\n\tfor k, v := range headers {\n\t\tr.Header.Set(k, v)\n\t}\n\treturn r\n}\n"
  },
  {
    "path": "request/oauth2.go",
    "content": "package request\n\nimport (\n\t\"strings\"\n)\n\n// Strips 'Bearer ' prefix from bearer token string\nfunc stripBearerPrefixFromTokenString(tok string) (string, error) {\n\t// Should be a bearer token\n\tif len(tok) > 6 && strings.ToUpper(tok[0:7]) == \"BEARER \" {\n\t\treturn tok[7:], nil\n\t}\n\treturn tok, nil\n}\n\n// Extract bearer token from Authorization header\n// Uses PostExtractionFilter to strip \"Bearer \" prefix from header\nvar AuthorizationHeaderExtractor = &PostExtractionFilter{\n\tHeaderExtractor{\"Authorization\"},\n\tstripBearerPrefixFromTokenString,\n}\n\n// Extractor for OAuth2 access tokens.  Looks in 'Authorization'\n// header then 'access_token' argument for a token.\nvar OAuth2Extractor = &MultiExtractor{\n\tAuthorizationHeaderExtractor,\n\tArgumentExtractor{\"access_token\"},\n}\n"
  },
  {
    "path": "request/request.go",
    "content": "package request\n\nimport (\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"net/http\"\n)\n\n// Extract and parse a JWT token from an HTTP request.\n// This behaves the same as Parse, but accepts a request and an extractor\n// instead of a token string.  The Extractor interface allows you to define\n// the logic for extracting a token.  Several useful implementations are provided.\n//\n// You can provide options to modify parsing behavior\nfunc ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc, options ...ParseFromRequestOption) (token *jwt.Token, err error) {\n\t// Create basic parser struct\n\tp := &fromRequestParser{req, extractor, nil, nil}\n\n\t// Handle options\n\tfor _, option := range options {\n\t\toption(p)\n\t}\n\n\t// Set defaults\n\tif p.claims == nil {\n\t\tp.claims = jwt.MapClaims{}\n\t}\n\tif p.parser == nil {\n\t\tp.parser = &jwt.Parser{}\n\t}\n\n\t// perform extract\n\ttokenString, err := p.extractor.ExtractToken(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// perform parse\n\treturn p.parser.ParseWithClaims(tokenString, p.claims, keyFunc)\n}\n\n// ParseFromRequest but with custom Claims type\n// DEPRECATED: use ParseFromRequest and the WithClaims option\nfunc ParseFromRequestWithClaims(req *http.Request, extractor Extractor, claims jwt.Claims, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) {\n\treturn ParseFromRequest(req, extractor, keyFunc, WithClaims(claims))\n}\n\ntype fromRequestParser struct {\n\treq       *http.Request\n\textractor Extractor\n\tclaims    jwt.Claims\n\tparser    *jwt.Parser\n}\n\ntype ParseFromRequestOption func(*fromRequestParser)\n\n// Parse with custom claims\nfunc WithClaims(claims jwt.Claims) ParseFromRequestOption {\n\treturn func(p *fromRequestParser) {\n\t\tp.claims = claims\n\t}\n}\n\n// Parse using a custom parser\nfunc WithParser(parser *jwt.Parser) ParseFromRequestOption {\n\treturn func(p *fromRequestParser) {\n\t\tp.parser = parser\n\t}\n}\n"
  },
  {
    "path": "request/request_test.go",
    "content": "package request\n\nimport (\n\t\"fmt\"\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"github.com/dgrijalva/jwt-go/test\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n)\n\nvar requestTestData = []struct {\n\tname      string\n\tclaims    jwt.MapClaims\n\textractor Extractor\n\theaders   map[string]string\n\tquery     url.Values\n\tvalid     bool\n}{\n\t{\n\t\t\"authorization bearer token\",\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tAuthorizationHeaderExtractor,\n\t\tmap[string]string{\"Authorization\": \"Bearer %v\"},\n\t\turl.Values{},\n\t\ttrue,\n\t},\n\t{\n\t\t\"oauth bearer token - header\",\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tOAuth2Extractor,\n\t\tmap[string]string{\"Authorization\": \"Bearer %v\"},\n\t\turl.Values{},\n\t\ttrue,\n\t},\n\t{\n\t\t\"oauth bearer token - url\",\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tOAuth2Extractor,\n\t\tmap[string]string{},\n\t\turl.Values{\"access_token\": {\"%v\"}},\n\t\ttrue,\n\t},\n\t{\n\t\t\"url token\",\n\t\tjwt.MapClaims{\"foo\": \"bar\"},\n\t\tArgumentExtractor{\"token\"},\n\t\tmap[string]string{},\n\t\turl.Values{\"token\": {\"%v\"}},\n\t\ttrue,\n\t},\n}\n\nfunc TestParseRequest(t *testing.T) {\n\t// load keys from disk\n\tprivateKey := test.LoadRSAPrivateKeyFromDisk(\"../test/sample_key\")\n\tpublicKey := test.LoadRSAPublicKeyFromDisk(\"../test/sample_key.pub\")\n\tkeyfunc := func(*jwt.Token) (interface{}, error) {\n\t\treturn publicKey, nil\n\t}\n\n\t// Bearer token request\n\tfor _, data := range requestTestData {\n\t\t// Make token from claims\n\t\ttokenString := test.MakeSampleToken(data.claims, privateKey)\n\n\t\t// Make query string\n\t\tfor k, vv := range data.query {\n\t\t\tfor i, v := range vv {\n\t\t\t\tif strings.Contains(v, \"%v\") {\n\t\t\t\t\tdata.query[k][i] = fmt.Sprintf(v, tokenString)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Make request from test struct\n\t\tr, _ := http.NewRequest(\"GET\", fmt.Sprintf(\"/?%v\", data.query.Encode()), nil)\n\t\tfor k, v := range data.headers {\n\t\t\tif strings.Contains(v, \"%v\") {\n\t\t\t\tr.Header.Set(k, fmt.Sprintf(v, tokenString))\n\t\t\t} else {\n\t\t\t\tr.Header.Set(k, tokenString)\n\t\t\t}\n\t\t}\n\t\ttoken, err := ParseFromRequestWithClaims(r, data.extractor, jwt.MapClaims{}, keyfunc)\n\n\t\tif token == nil {\n\t\t\tt.Errorf(\"[%v] Token was not found: %v\", data.name, err)\n\t\t\tcontinue\n\t\t}\n\t\tif !reflect.DeepEqual(data.claims, token.Claims) {\n\t\t\tt.Errorf(\"[%v] Claims mismatch. Expecting: %v  Got: %v\", data.name, data.claims, token.Claims)\n\t\t}\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying token: %v\", data.name, err)\n\t\t}\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid token passed validation\", data.name)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "rsa.go",
    "content": "package jwt\n\nimport (\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n)\n\n// Implements the RSA family of signing methods signing methods\n// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation\ntype SigningMethodRSA struct {\n\tName string\n\tHash crypto.Hash\n}\n\n// Specific instances for RS256 and company\nvar (\n\tSigningMethodRS256 *SigningMethodRSA\n\tSigningMethodRS384 *SigningMethodRSA\n\tSigningMethodRS512 *SigningMethodRSA\n)\n\nfunc init() {\n\t// RS256\n\tSigningMethodRS256 = &SigningMethodRSA{\"RS256\", crypto.SHA256}\n\tRegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod {\n\t\treturn SigningMethodRS256\n\t})\n\n\t// RS384\n\tSigningMethodRS384 = &SigningMethodRSA{\"RS384\", crypto.SHA384}\n\tRegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod {\n\t\treturn SigningMethodRS384\n\t})\n\n\t// RS512\n\tSigningMethodRS512 = &SigningMethodRSA{\"RS512\", crypto.SHA512}\n\tRegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod {\n\t\treturn SigningMethodRS512\n\t})\n}\n\nfunc (m *SigningMethodRSA) Alg() string {\n\treturn m.Name\n}\n\n// Implements the Verify method from SigningMethod\n// For this signing method, must be an *rsa.PublicKey structure.\nfunc (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {\n\tvar err error\n\n\t// Decode the signature\n\tvar sig []byte\n\tif sig, err = DecodeSegment(signature); err != nil {\n\t\treturn err\n\t}\n\n\tvar rsaKey *rsa.PublicKey\n\tvar ok bool\n\n\tif rsaKey, ok = key.(*rsa.PublicKey); !ok {\n\t\treturn ErrInvalidKeyType\n\t}\n\n\t// Create hasher\n\tif !m.Hash.Available() {\n\t\treturn ErrHashUnavailable\n\t}\n\thasher := m.Hash.New()\n\thasher.Write([]byte(signingString))\n\n\t// Verify the signature\n\treturn rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)\n}\n\n// Implements the Sign method from SigningMethod\n// For this signing method, must be an *rsa.PrivateKey structure.\nfunc (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {\n\tvar rsaKey *rsa.PrivateKey\n\tvar ok bool\n\n\t// Validate type of key\n\tif rsaKey, ok = key.(*rsa.PrivateKey); !ok {\n\t\treturn \"\", ErrInvalidKey\n\t}\n\n\t// Create the hasher\n\tif !m.Hash.Available() {\n\t\treturn \"\", ErrHashUnavailable\n\t}\n\n\thasher := m.Hash.New()\n\thasher.Write([]byte(signingString))\n\n\t// Sign the string and return the encoded bytes\n\tif sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {\n\t\treturn EncodeSegment(sigBytes), nil\n\t} else {\n\t\treturn \"\", err\n\t}\n}\n"
  },
  {
    "path": "rsa_pss.go",
    "content": "// +build go1.4\n\npackage jwt\n\nimport (\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n)\n\n// Implements the RSAPSS family of signing methods signing methods\ntype SigningMethodRSAPSS struct {\n\t*SigningMethodRSA\n\tOptions *rsa.PSSOptions\n\t// VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.\n\t// Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow\n\t// https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.\n\t// See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.\n\tVerifyOptions *rsa.PSSOptions\n}\n\n// Specific instances for RS/PS and company.\nvar (\n\tSigningMethodPS256 *SigningMethodRSAPSS\n\tSigningMethodPS384 *SigningMethodRSAPSS\n\tSigningMethodPS512 *SigningMethodRSAPSS\n)\n\nfunc init() {\n\t// PS256\n\tSigningMethodPS256 = &SigningMethodRSAPSS{\n\t\tSigningMethodRSA: &SigningMethodRSA{\n\t\t\tName: \"PS256\",\n\t\t\tHash: crypto.SHA256,\n\t\t},\n\t\tOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthEqualsHash,\n\t\t},\n\t\tVerifyOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthAuto,\n\t\t},\n\t}\n\tRegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {\n\t\treturn SigningMethodPS256\n\t})\n\n\t// PS384\n\tSigningMethodPS384 = &SigningMethodRSAPSS{\n\t\tSigningMethodRSA: &SigningMethodRSA{\n\t\t\tName: \"PS384\",\n\t\t\tHash: crypto.SHA384,\n\t\t},\n\t\tOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthEqualsHash,\n\t\t},\n\t\tVerifyOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthAuto,\n\t\t},\n\t}\n\tRegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {\n\t\treturn SigningMethodPS384\n\t})\n\n\t// PS512\n\tSigningMethodPS512 = &SigningMethodRSAPSS{\n\t\tSigningMethodRSA: &SigningMethodRSA{\n\t\t\tName: \"PS512\",\n\t\t\tHash: crypto.SHA512,\n\t\t},\n\t\tOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthEqualsHash,\n\t\t},\n\t\tVerifyOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthAuto,\n\t\t},\n\t}\n\tRegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {\n\t\treturn SigningMethodPS512\n\t})\n}\n\n// Implements the Verify method from SigningMethod\n// For this verify method, key must be an rsa.PublicKey struct\nfunc (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error {\n\tvar err error\n\n\t// Decode the signature\n\tvar sig []byte\n\tif sig, err = DecodeSegment(signature); err != nil {\n\t\treturn err\n\t}\n\n\tvar rsaKey *rsa.PublicKey\n\tswitch k := key.(type) {\n\tcase *rsa.PublicKey:\n\t\trsaKey = k\n\tdefault:\n\t\treturn ErrInvalidKey\n\t}\n\n\t// Create hasher\n\tif !m.Hash.Available() {\n\t\treturn ErrHashUnavailable\n\t}\n\thasher := m.Hash.New()\n\thasher.Write([]byte(signingString))\n\n\topts := m.Options\n\tif m.VerifyOptions != nil {\n\t\topts = m.VerifyOptions\n\t}\n\n\treturn rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)\n}\n\n// Implements the Sign method from SigningMethod\n// For this signing method, key must be an rsa.PrivateKey struct\nfunc (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) {\n\tvar rsaKey *rsa.PrivateKey\n\n\tswitch k := key.(type) {\n\tcase *rsa.PrivateKey:\n\t\trsaKey = k\n\tdefault:\n\t\treturn \"\", ErrInvalidKeyType\n\t}\n\n\t// Create the hasher\n\tif !m.Hash.Available() {\n\t\treturn \"\", ErrHashUnavailable\n\t}\n\n\thasher := m.Hash.New()\n\thasher.Write([]byte(signingString))\n\n\t// Sign the string and return the encoded bytes\n\tif sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {\n\t\treturn EncodeSegment(sigBytes), nil\n\t} else {\n\t\treturn \"\", err\n\t}\n}\n"
  },
  {
    "path": "rsa_pss_test.go",
    "content": "// +build go1.4\n\npackage jwt_test\n\nimport (\n\t\"crypto/rsa\"\n\t\"io/ioutil\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"github.com/dgrijalva/jwt-go/test\"\n)\n\nvar rsaPSSTestData = []struct {\n\tname        string\n\ttokenString string\n\talg         string\n\tclaims      map[string]interface{}\n\tvalid       bool\n}{\n\t{\n\t\t\"Basic PS256\",\n\t\t\"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9w\",\n\t\t\"PS256\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic PS384\",\n\t\t\"eyJhbGciOiJQUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.w7-qqgj97gK4fJsq_DCqdYQiylJjzWONvD0qWWWhqEOFk2P1eDULPnqHRnjgTXoO4HAw4YIWCsZPet7nR3Xxq4ZhMqvKW8b7KlfRTb9cH8zqFvzMmybQ4jv2hKc3bXYqVow3AoR7hN_CWXI3Dv6Kd2X5xhtxRHI6IL39oTVDUQ74LACe-9t4c3QRPuj6Pq1H4FAT2E2kW_0KOc6EQhCLWEhm2Z2__OZskDC8AiPpP8Kv4k2vB7l0IKQu8Pr4RcNBlqJdq8dA5D3hk5TLxP8V5nG1Ib80MOMMqoS3FQvSLyolFX-R_jZ3-zfq6Ebsqr0yEb0AH2CfsECF7935Pa0FKQ\",\n\t\t\"PS384\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic PS512\",\n\t\t\"eyJhbGciOiJQUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.GX1HWGzFaJevuSLavqqFYaW8_TpvcjQ8KfC5fXiSDzSiT9UD9nB_ikSmDNyDILNdtjZLSvVKfXxZJqCfefxAtiozEDDdJthZ-F0uO4SPFHlGiXszvKeodh7BuTWRI2wL9-ZO4mFa8nq3GMeQAfo9cx11i7nfN8n2YNQ9SHGovG7_T_AvaMZB_jT6jkDHpwGR9mz7x1sycckEo6teLdHRnH_ZdlHlxqknmyTu8Odr5Xh0sJFOL8BepWbbvIIn-P161rRHHiDWFv6nhlHwZnVzjx7HQrWSGb6-s2cdLie9QL_8XaMcUpjLkfOMKkDOfHo6AvpL7Jbwi83Z2ZTHjJWB-A\",\n\t\t\"PS512\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"basic PS256 invalid: foo => bar\",\n\t\t\"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9W\",\n\t\t\"PS256\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\tfalse,\n\t},\n}\n\nfunc TestRSAPSSVerify(t *testing.T) {\n\tvar err error\n\n\tkey, _ := ioutil.ReadFile(\"test/sample_key.pub\")\n\tvar rsaPSSKey *rsa.PublicKey\n\tif rsaPSSKey, err = jwt.ParseRSAPublicKeyFromPEM(key); err != nil {\n\t\tt.Errorf(\"Unable to parse RSA public key: %v\", err)\n\t}\n\n\tfor _, data := range rsaPSSTestData {\n\t\tparts := strings.Split(data.tokenString, \".\")\n\n\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\terr := method.Verify(strings.Join(parts[0:2], \".\"), parts[2], rsaPSSKey)\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying key: %v\", data.name, err)\n\t\t}\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid key passed validation\", data.name)\n\t\t}\n\t}\n}\n\nfunc TestRSAPSSSign(t *testing.T) {\n\tvar err error\n\n\tkey, _ := ioutil.ReadFile(\"test/sample_key\")\n\tvar rsaPSSKey *rsa.PrivateKey\n\tif rsaPSSKey, err = jwt.ParseRSAPrivateKeyFromPEM(key); err != nil {\n\t\tt.Errorf(\"Unable to parse RSA private key: %v\", err)\n\t}\n\n\tfor _, data := range rsaPSSTestData {\n\t\tif data.valid {\n\t\t\tparts := strings.Split(data.tokenString, \".\")\n\t\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\t\tsig, err := method.Sign(strings.Join(parts[0:2], \".\"), rsaPSSKey)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%v] Error signing token: %v\", data.name, err)\n\t\t\t}\n\t\t\tif sig == parts[2] {\n\t\t\t\tt.Errorf(\"[%v] Signatures shouldn't match\\nnew:\\n%v\\noriginal:\\n%v\", data.name, sig, parts[2])\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestRSAPSSSaltLengthCompatibility(t *testing.T) {\n\t// Fails token verify, if salt length is auto.\n\tps256SaltLengthEqualsHash := &jwt.SigningMethodRSAPSS{\n\t\tSigningMethodRSA: jwt.SigningMethodPS256.SigningMethodRSA,\n\t\tOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthEqualsHash,\n\t\t},\n\t}\n\n\t// Behaves as before https://github.com/dgrijalva/jwt-go/issues/285 fix.\n\tps256SaltLengthAuto := &jwt.SigningMethodRSAPSS{\n\t\tSigningMethodRSA: jwt.SigningMethodPS256.SigningMethodRSA,\n\t\tOptions: &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthAuto,\n\t\t},\n\t}\n\tif !verify(jwt.SigningMethodPS256, makeToken(ps256SaltLengthEqualsHash)) {\n\t\tt.Error(\"SigningMethodPS256 should accept salt length that is defined in RFC\")\n\t}\n\tif !verify(ps256SaltLengthEqualsHash, makeToken(jwt.SigningMethodPS256)) {\n\t\tt.Error(\"Sign by SigningMethodPS256 should have salt length that is defined in RFC\")\n\t}\n\tif !verify(jwt.SigningMethodPS256, makeToken(ps256SaltLengthAuto)) {\n\t\tt.Error(\"SigningMethodPS256 should accept auto salt length to be compatible with previous versions\")\n\t}\n\tif !verify(ps256SaltLengthAuto, makeToken(jwt.SigningMethodPS256)) {\n\t\tt.Error(\"Sign by SigningMethodPS256 should be accepted by previous versions\")\n\t}\n\tif verify(ps256SaltLengthEqualsHash, makeToken(ps256SaltLengthAuto)) {\n\t\tt.Error(\"Auto salt length should be not accepted, when RFC salt length is required\")\n\t}\n}\n\nfunc makeToken(method jwt.SigningMethod) string {\n\ttoken := jwt.NewWithClaims(method, jwt.StandardClaims{\n\t\tIssuer:   \"example\",\n\t\tIssuedAt: time.Now().Unix(),\n\t})\n\tprivateKey := test.LoadRSAPrivateKeyFromDisk(\"test/sample_key\")\n\tsigned, err := token.SignedString(privateKey)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn signed\n}\n\nfunc verify(signingMethod jwt.SigningMethod, token string) bool {\n\tsegments := strings.Split(token, \".\")\n\terr := signingMethod.Verify(strings.Join(segments[:2], \".\"), segments[2], test.LoadRSAPublicKeyFromDisk(\"test/sample_key.pub\"))\n\treturn err == nil\n}\n"
  },
  {
    "path": "rsa_test.go",
    "content": "package jwt_test\n\nimport (\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"io/ioutil\"\n\t\"strings\"\n\t\"testing\"\n)\n\nvar rsaTestData = []struct {\n\tname        string\n\ttokenString string\n\talg         string\n\tclaims      map[string]interface{}\n\tvalid       bool\n}{\n\t{\n\t\t\"Basic RS256\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\t\"RS256\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic RS384\",\n\t\t\"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw\",\n\t\t\"RS384\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"Basic RS512\",\n\t\t\"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.zBlLlmRrUxx4SJPUbV37Q1joRcI9EW13grnKduK3wtYKmDXbgDpF1cZ6B-2Jsm5RB8REmMiLpGms-EjXhgnyh2TSHE-9W2gA_jvshegLWtwRVDX40ODSkTb7OVuaWgiy9y7llvcknFBTIg-FnVPVpXMmeV_pvwQyhaz1SSwSPrDyxEmksz1hq7YONXhXPpGaNbMMeDTNP_1oj8DZaqTIL9TwV8_1wb2Odt_Fy58Ke2RVFijsOLdnyEAjt2n9Mxihu9i3PhNBkkxa2GbnXBfq3kzvZ_xxGGopLdHhJjcGWXO-NiwI9_tiu14NRv4L2xC0ItD9Yz68v2ZIZEp_DuzwRQ\",\n\t\t\"RS512\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\ttrue,\n\t},\n\t{\n\t\t\"basic invalid: foo => bar\",\n\t\t\"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg\",\n\t\t\"RS256\",\n\t\tmap[string]interface{}{\"foo\": \"bar\"},\n\t\tfalse,\n\t},\n}\n\nfunc TestRSAVerify(t *testing.T) {\n\tkeyData, _ := ioutil.ReadFile(\"test/sample_key.pub\")\n\tkey, _ := jwt.ParseRSAPublicKeyFromPEM(keyData)\n\n\tfor _, data := range rsaTestData {\n\t\tparts := strings.Split(data.tokenString, \".\")\n\n\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\terr := method.Verify(strings.Join(parts[0:2], \".\"), parts[2], key)\n\t\tif data.valid && err != nil {\n\t\t\tt.Errorf(\"[%v] Error while verifying key: %v\", data.name, err)\n\t\t}\n\t\tif !data.valid && err == nil {\n\t\t\tt.Errorf(\"[%v] Invalid key passed validation\", data.name)\n\t\t}\n\t}\n}\n\nfunc TestRSASign(t *testing.T) {\n\tkeyData, _ := ioutil.ReadFile(\"test/sample_key\")\n\tkey, _ := jwt.ParseRSAPrivateKeyFromPEM(keyData)\n\n\tfor _, data := range rsaTestData {\n\t\tif data.valid {\n\t\t\tparts := strings.Split(data.tokenString, \".\")\n\t\t\tmethod := jwt.GetSigningMethod(data.alg)\n\t\t\tsig, err := method.Sign(strings.Join(parts[0:2], \".\"), key)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%v] Error signing token: %v\", data.name, err)\n\t\t\t}\n\t\t\tif sig != parts[2] {\n\t\t\t\tt.Errorf(\"[%v] Incorrect signature.\\nwas:\\n%v\\nexpecting:\\n%v\", data.name, sig, parts[2])\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) {\n\tkey, _ := ioutil.ReadFile(\"test/sample_key.pub\")\n\tparsedKey, err := jwt.ParseRSAPublicKeyFromPEM(key)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\ttestData := rsaTestData[0]\n\tparts := strings.Split(testData.tokenString, \".\")\n\terr = jwt.SigningMethodRS256.Verify(strings.Join(parts[0:2], \".\"), parts[2], parsedKey)\n\tif err != nil {\n\t\tt.Errorf(\"[%v] Error while verifying key: %v\", testData.name, err)\n\t}\n}\n\nfunc TestRSAWithPreParsedPrivateKey(t *testing.T) {\n\tkey, _ := ioutil.ReadFile(\"test/sample_key\")\n\tparsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\ttestData := rsaTestData[0]\n\tparts := strings.Split(testData.tokenString, \".\")\n\tsig, err := jwt.SigningMethodRS256.Sign(strings.Join(parts[0:2], \".\"), parsedKey)\n\tif err != nil {\n\t\tt.Errorf(\"[%v] Error signing token: %v\", testData.name, err)\n\t}\n\tif sig != parts[2] {\n\t\tt.Errorf(\"[%v] Incorrect signature.\\nwas:\\n%v\\nexpecting:\\n%v\", testData.name, sig, parts[2])\n\t}\n}\n\nfunc TestRSAKeyParsing(t *testing.T) {\n\tkey, _ := ioutil.ReadFile(\"test/sample_key\")\n\tsecureKey, _ := ioutil.ReadFile(\"test/privateSecure.pem\")\n\tpubKey, _ := ioutil.ReadFile(\"test/sample_key.pub\")\n\tbadKey := []byte(\"All your base are belong to key\")\n\n\t// Test parsePrivateKey\n\tif _, e := jwt.ParseRSAPrivateKeyFromPEM(key); e != nil {\n\t\tt.Errorf(\"Failed to parse valid private key: %v\", e)\n\t}\n\n\tif k, e := jwt.ParseRSAPrivateKeyFromPEM(pubKey); e == nil {\n\t\tt.Errorf(\"Parsed public key as valid private key: %v\", k)\n\t}\n\n\tif k, e := jwt.ParseRSAPrivateKeyFromPEM(badKey); e == nil {\n\t\tt.Errorf(\"Parsed invalid key as valid private key: %v\", k)\n\t}\n\n\tif _, e := jwt.ParseRSAPrivateKeyFromPEMWithPassword(secureKey, \"password\"); e != nil {\n\t\tt.Errorf(\"Failed to parse valid private key with password: %v\", e)\n\t}\n\n\tif k, e := jwt.ParseRSAPrivateKeyFromPEMWithPassword(secureKey, \"123132\"); e == nil {\n\t\tt.Errorf(\"Parsed private key with invalid password %v\", k)\n\t}\n\n\t// Test parsePublicKey\n\tif _, e := jwt.ParseRSAPublicKeyFromPEM(pubKey); e != nil {\n\t\tt.Errorf(\"Failed to parse valid public key: %v\", e)\n\t}\n\n\tif k, e := jwt.ParseRSAPublicKeyFromPEM(key); e == nil {\n\t\tt.Errorf(\"Parsed private key as valid public key: %v\", k)\n\t}\n\n\tif k, e := jwt.ParseRSAPublicKeyFromPEM(badKey); e == nil {\n\t\tt.Errorf(\"Parsed invalid key as valid private key: %v\", k)\n\t}\n\n}\n\nfunc BenchmarkRS256Signing(b *testing.B) {\n\tkey, _ := ioutil.ReadFile(\"test/sample_key\")\n\tparsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\n\tbenchmarkSigning(b, jwt.SigningMethodRS256, parsedKey)\n}\n\nfunc BenchmarkRS384Signing(b *testing.B) {\n\tkey, _ := ioutil.ReadFile(\"test/sample_key\")\n\tparsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\n\tbenchmarkSigning(b, jwt.SigningMethodRS384, parsedKey)\n}\n\nfunc BenchmarkRS512Signing(b *testing.B) {\n\tkey, _ := ioutil.ReadFile(\"test/sample_key\")\n\tparsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\n\tbenchmarkSigning(b, jwt.SigningMethodRS512, parsedKey)\n}\n"
  },
  {
    "path": "rsa_utils.go",
    "content": "package jwt\n\nimport (\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n)\n\nvar (\n\tErrKeyMustBePEMEncoded = errors.New(\"Invalid Key: Key must be a PEM encoded PKCS1 or PKCS8 key\")\n\tErrNotRSAPrivateKey    = errors.New(\"Key is not a valid RSA private key\")\n\tErrNotRSAPublicKey     = errors.New(\"Key is not a valid RSA public key\")\n)\n\n// Parse PEM encoded PKCS1 or PKCS8 private key\nfunc ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {\n\tvar err error\n\n\t// Parse PEM block\n\tvar block *pem.Block\n\tif block, _ = pem.Decode(key); block == nil {\n\t\treturn nil, ErrKeyMustBePEMEncoded\n\t}\n\n\tvar parsedKey interface{}\n\tif parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {\n\t\tif parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar pkey *rsa.PrivateKey\n\tvar ok bool\n\tif pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {\n\t\treturn nil, ErrNotRSAPrivateKey\n\t}\n\n\treturn pkey, nil\n}\n\n// Parse PEM encoded PKCS1 or PKCS8 private key protected with password\nfunc ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) {\n\tvar err error\n\n\t// Parse PEM block\n\tvar block *pem.Block\n\tif block, _ = pem.Decode(key); block == nil {\n\t\treturn nil, ErrKeyMustBePEMEncoded\n\t}\n\n\tvar parsedKey interface{}\n\n\tvar blockDecrypted []byte\n\tif blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil {\n\t\tif parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar pkey *rsa.PrivateKey\n\tvar ok bool\n\tif pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {\n\t\treturn nil, ErrNotRSAPrivateKey\n\t}\n\n\treturn pkey, nil\n}\n\n// Parse PEM encoded PKCS1 or PKCS8 public key\nfunc ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {\n\tvar err error\n\n\t// Parse PEM block\n\tvar block *pem.Block\n\tif block, _ = pem.Decode(key); block == nil {\n\t\treturn nil, ErrKeyMustBePEMEncoded\n\t}\n\n\t// Parse the key\n\tvar parsedKey interface{}\n\tif parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {\n\t\tif cert, err := x509.ParseCertificate(block.Bytes); err == nil {\n\t\t\tparsedKey = cert.PublicKey\n\t\t} else {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar pkey *rsa.PublicKey\n\tvar ok bool\n\tif pkey, ok = parsedKey.(*rsa.PublicKey); !ok {\n\t\treturn nil, ErrNotRSAPublicKey\n\t}\n\n\treturn pkey, nil\n}\n"
  },
  {
    "path": "signing_method.go",
    "content": "package jwt\n\nimport (\n\t\"sync\"\n)\n\nvar signingMethods = map[string]func() SigningMethod{}\nvar signingMethodLock = new(sync.RWMutex)\n\n// Implement SigningMethod to add new methods for signing or verifying tokens.\ntype SigningMethod interface {\n\tVerify(signingString, signature string, key interface{}) error // Returns nil if signature is valid\n\tSign(signingString string, key interface{}) (string, error)    // Returns encoded signature or error\n\tAlg() string                                                   // returns the alg identifier for this method (example: 'HS256')\n}\n\n// Register the \"alg\" name and a factory function for signing method.\n// This is typically done during init() in the method's implementation\nfunc RegisterSigningMethod(alg string, f func() SigningMethod) {\n\tsigningMethodLock.Lock()\n\tdefer signingMethodLock.Unlock()\n\n\tsigningMethods[alg] = f\n}\n\n// Get a signing method from an \"alg\" string\nfunc GetSigningMethod(alg string) (method SigningMethod) {\n\tsigningMethodLock.RLock()\n\tdefer signingMethodLock.RUnlock()\n\n\tif methodF, ok := signingMethods[alg]; ok {\n\t\tmethod = methodF()\n\t}\n\treturn\n}\n"
  },
  {
    "path": "test/ec256-private.pem",
    "content": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAh5qA3rmqQQuu0vbKV/+zouz/y/Iy2pLpIcWUSyImSwoAoGCCqGSM49\nAwEHoUQDQgAEYD54V/vp+54P9DXarYqx4MPcm+HKRIQzNasYSoRQHQ/6S6Ps8tpM\ncT+KvIIC8W/e9k0W7Cm72M1P9jU7SLf/vg==\n-----END EC PRIVATE KEY-----\n"
  },
  {
    "path": "test/ec256-public.pem",
    "content": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYD54V/vp+54P9DXarYqx4MPcm+HK\nRIQzNasYSoRQHQ/6S6Ps8tpMcT+KvIIC8W/e9k0W7Cm72M1P9jU7SLf/vg==\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "test/ec384-private.pem",
    "content": "-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDCaCvMHKhcG/qT7xsNLYnDT7sE/D+TtWIol1ROdaK1a564vx5pHbsRy\nSEKcIxISi1igBwYFK4EEACKhZANiAATYa7rJaU7feLMqrAx6adZFNQOpaUH/Uylb\nZLriOLON5YFVwtVUpO1FfEXZUIQpptRPtc5ixIPY658yhBSb6irfIJUSP9aYTflJ\nGKk/mDkK4t8mWBzhiD5B6jg9cEGhGgA=\n-----END EC PRIVATE KEY-----\n"
  },
  {
    "path": "test/ec384-public.pem",
    "content": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2Gu6yWlO33izKqwMemnWRTUDqWlB/1Mp\nW2S64jizjeWBVcLVVKTtRXxF2VCEKabUT7XOYsSD2OufMoQUm+oq3yCVEj/WmE35\nSRipP5g5CuLfJlgc4Yg+Qeo4PXBBoRoA\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "test/ec512-private.pem",
    "content": "-----BEGIN EC PRIVATE KEY-----\nMIHcAgEBBEIB0pE4uFaWRx7t03BsYlYvF1YvKaBGyvoakxnodm9ou0R9wC+sJAjH\nQZZJikOg4SwNqgQ/hyrOuDK2oAVHhgVGcYmgBwYFK4EEACOhgYkDgYYABAAJXIuw\n12MUzpHggia9POBFYXSxaOGKGbMjIyDI+6q7wi7LMw3HgbaOmgIqFG72o8JBQwYN\n4IbXHf+f86CRY1AA2wHzbHvt6IhkCXTNxBEffa1yMUgu8n9cKKF2iLgyQKcKqW33\n8fGOw/n3Rm2Yd/EB56u2rnD29qS+nOM9eGS+gy39OQ==\n-----END EC PRIVATE KEY-----\n"
  },
  {
    "path": "test/ec512-public.pem",
    "content": "-----BEGIN PUBLIC KEY-----\nMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQACVyLsNdjFM6R4IImvTzgRWF0sWjh\nihmzIyMgyPuqu8IuyzMNx4G2jpoCKhRu9qPCQUMGDeCG1x3/n/OgkWNQANsB82x7\n7eiIZAl0zcQRH32tcjFILvJ/XCihdoi4MkCnCqlt9/HxjsP590ZtmHfxAeertq5w\n9vakvpzjPXhkvoMt/Tk=\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "test/helpers.go",
    "content": "package test\n\nimport (\n\t\"crypto/rsa\"\n\t\"github.com/dgrijalva/jwt-go\"\n\t\"io/ioutil\"\n)\n\nfunc LoadRSAPrivateKeyFromDisk(location string) *rsa.PrivateKey {\n\tkeyData, e := ioutil.ReadFile(location)\n\tif e != nil {\n\t\tpanic(e.Error())\n\t}\n\tkey, e := jwt.ParseRSAPrivateKeyFromPEM(keyData)\n\tif e != nil {\n\t\tpanic(e.Error())\n\t}\n\treturn key\n}\n\nfunc LoadRSAPublicKeyFromDisk(location string) *rsa.PublicKey {\n\tkeyData, e := ioutil.ReadFile(location)\n\tif e != nil {\n\t\tpanic(e.Error())\n\t}\n\tkey, e := jwt.ParseRSAPublicKeyFromPEM(keyData)\n\tif e != nil {\n\t\tpanic(e.Error())\n\t}\n\treturn key\n}\n\nfunc MakeSampleToken(c jwt.Claims, key interface{}) string {\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodRS256, c)\n\ts, e := token.SignedString(key)\n\n\tif e != nil {\n\t\tpanic(e.Error())\n\t}\n\n\treturn s\n}\n"
  },
  {
    "path": "test/hmacTestKey",
    "content": "\u0003#5K+\u000f~\u0006ew{Z(T(\u000fP.Z\u0006Gwb=\"=.!r\u0005.O\b͚gЀ"
  },
  {
    "path": "test/privateSecure.pem",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,7487BB8910A3741B\n\niL7m48mbFSIy1Y5xbXWwPTR07ufxu7o+myGUE+AdDeWWISkd5W6Gl44oX/jgXldS\nmL/ntUXoZzQz2WKEYLwssAtSTGF+QgSIMvV5faiP+pLYvWgk0oVr42po00CvADFL\neDAJC7LgagYifS1l4EAK4MY8RGCHyJWEN5JAr0fc/Haa3WfWZ009kOWAp8MDuYxB\nhQlCKUmnUpXCp5c6jwbjlyinLj8XwzzjZ/rVRsY+t2Z0Vcd5qzR5BV8IJCqbG5Py\nz15/EFgMG2N2eYMsiEKgdXeKW2H5XIoWyun/3pBigWaDnTtiWSt9kz2MplqYfIT7\nF+0XE3gdDGalAeN3YwFPHCkxxBmcI+s6lQG9INmf2/gkJQ+MOZBVXKmGLv6Qis3l\n0eyUz1yZvNzf0zlcUBjiPulLF3peThHMEzhSsATfPomyg5NJ0X7ttd0ybnq+sPe4\nqg2OJ8qNhYrqnx7Xlvj61+B2NAZVHvIioma1FzqX8DxQYrnR5S6DJExDqvzNxEz6\n5VPQlH2Ig4hTvNzla84WgJ6USc/2SS4ehCReiNvfeNG9sPZKQnr/Ss8KPIYsKGcC\nPz/vEqbWDmJwHb7KixCQKPt1EbD+/uf0YnhskOWM15YiFbYAOZKJ5rcbz2Zu66vg\nGAmqcBsHeFR3s/bObEzjxOmMfSr1vzvr4ActNJWVtfNKZNobSehZiMSHL54AXAZW\nYj48pwTbf7b1sbF0FeCuwTFiYxM+yiZVO5ciYOfmo4HUg53PjknKpcKtEFSj02P1\n8JRBSb++V0IeMDyZLl12zgURDsvualbJMMBBR8emIpF13h0qdyah431gDhHGBnnC\nJ5UDGq21/flFjzz0x/Okjwf7mPK5pcmF+uW7AxtHqws6m93yD5+RFmfZ8cb/8CL8\njmsQslj+OIE64ykkRoJWpNBKyQjL3CnPnLmAB6TQKxegR94C7/hP1FvRW+W0AgZy\ng2QczKQU3KBQP18Ui1HTbkOUJT0Lsy4FnmJFCB/STPRo6NlJiATKHq/cqHWQUvZd\nd4oTMb1opKfs7AI9wiJBuskpGAECdRnVduml3dT4p//3BiP6K9ImWMSJeFpjFAFs\nAbBMKyitMs0Fyn9AJRPl23TKVQ3cYeSTxus4wLmx5ECSsHRV6g06nYjBp4GWEqSX\nRVclXF3zmy3b1+O5s2chJN6TrypzYSEYXJb1vvQLK0lNXqwxZAFV7Roi6xSG0fSY\nEAtdUifLonu43EkrLh55KEwkXdVV8xneUjh+TF8VgJKMnqDFfeHFdmN53YYh3n3F\nkpYSmVLRzQmLbH9dY+7kqvnsQm8y76vjug3p4IbEbHp/fNGf+gv7KDng1HyCl9A+\nOw/Hlr0NqCAIhminScbRsZ4SgbRTRgGEYZXvyOtQa/uL6I8t2NR4W7ynispMs0QL\nRD61i3++bQXuTi4i8dg3yqIfe9S22NHSzZY/lAHAmmc3r5NrQ1TM1hsSxXawT5CU\nanWFjbH6YQ/QplkkAqZMpropWn6ZdNDg/+BUjukDs0HZrbdGy846WxQUvE7G2bAw\nIFQ1SymBZBtfnZXhfAXOHoWh017p6HsIkb2xmFrigMj7Jh10VVhdWg==\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/sample_key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA4f5wg5l2hKsTeNem/V41fGnJm6gOdrj8ym3rFkEU/wT8RDtn\nSgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7mCpz9Er5qLaMXJwZxzHzAahlfA0i\ncqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBpHssPnpYGIn20ZZuNlX2BrClciHhC\nPUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2XrHhR+1DcKJzQBSTAGnpYVaqpsAR\nap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3bODIRe1AuTyHceAbewn8b462yEWKA\nRdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy7wIDAQABAoIBAQCwia1k7+2oZ2d3\nn6agCAbqIE1QXfCmh41ZqJHbOY3oRQG3X1wpcGH4Gk+O+zDVTV2JszdcOt7E5dAy\nMaomETAhRxB7hlIOnEN7WKm+dGNrKRvV0wDU5ReFMRHg31/Lnu8c+5BvGjZX+ky9\nPOIhFFYJqwCRlopGSUIxmVj5rSgtzk3iWOQXr+ah1bjEXvlxDOWkHN6YfpV5ThdE\nKdBIPGEVqa63r9n2h+qazKrtiRqJqGnOrHzOECYbRFYhexsNFz7YT02xdfSHn7gM\nIvabDDP/Qp0PjE1jdouiMaFHYnLBbgvlnZW9yuVf/rpXTUq/njxIXMmvmEyyvSDn\nFcFikB8pAoGBAPF77hK4m3/rdGT7X8a/gwvZ2R121aBcdPwEaUhvj/36dx596zvY\nmEOjrWfZhF083/nYWE2kVquj2wjs+otCLfifEEgXcVPTnEOPO9Zg3uNSL0nNQghj\nFuD3iGLTUBCtM66oTe0jLSslHe8gLGEQqyMzHOzYxNqibxcOZIe8Qt0NAoGBAO+U\nI5+XWjWEgDmvyC3TrOSf/KCGjtu0TSv30ipv27bDLMrpvPmD/5lpptTFwcxvVhCs\n2b+chCjlghFSWFbBULBrfci2FtliClOVMYrlNBdUSJhf3aYSG2Doe6Bgt1n2CpNn\n/iu37Y3NfemZBJA7hNl4dYe+f+uzM87cdQ214+jrAoGAXA0XxX8ll2+ToOLJsaNT\nOvNB9h9Uc5qK5X5w+7G7O998BN2PC/MWp8H+2fVqpXgNENpNXttkRm1hk1dych86\nEunfdPuqsX+as44oCyJGFHVBnWpm33eWQw9YqANRI+pCJzP08I5WK3osnPiwshd+\nhR54yjgfYhBFNI7B95PmEQkCgYBzFSz7h1+s34Ycr8SvxsOBWxymG5zaCsUbPsL0\n4aCgLScCHb9J+E86aVbbVFdglYa5Id7DPTL61ixhl7WZjujspeXZGSbmq0Kcnckb\nmDgqkLECiOJW2NHP/j0McAkDLL4tysF8TLDO8gvuvzNC+WQ6drO2ThrypLVZQ+ry\neBIPmwKBgEZxhqa0gVvHQG/7Od69KWj4eJP28kq13RhKay8JOoN0vPmspXJo1HY3\nCKuHRG+AP579dncdUnOMvfXOtkdM4vk0+hWASBQzM9xzVcztCa+koAugjVaLS9A+\n9uQoqEeVNTckxx0S2bYevRy7hGQmUJTyQm3j1zEUR5jpdbL83Fbq\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/sample_key.pub",
    "content": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4f5wg5l2hKsTeNem/V41\nfGnJm6gOdrj8ym3rFkEU/wT8RDtnSgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7\nmCpz9Er5qLaMXJwZxzHzAahlfA0icqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBp\nHssPnpYGIn20ZZuNlX2BrClciHhCPUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2\nXrHhR+1DcKJzQBSTAGnpYVaqpsARap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3b\nODIRe1AuTyHceAbewn8b462yEWKARdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy\n7wIDAQAB\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "token.go",
    "content": "package jwt\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"strings\"\n\t\"time\"\n)\n\n// TimeFunc provides the current time when parsing token to validate \"exp\" claim (expiration time).\n// You can override it to use another time value.  This is useful for testing or if your\n// server uses a different time zone than your tokens.\nvar TimeFunc = time.Now\n\n// Parse methods use this callback function to supply\n// the key for verification.  The function receives the parsed,\n// but unverified Token.  This allows you to use properties in the\n// Header of the token (such as `kid`) to identify which key to use.\ntype Keyfunc func(*Token) (interface{}, error)\n\n// A JWT Token.  Different fields will be used depending on whether you're\n// creating or parsing/verifying a token.\ntype Token struct {\n\tRaw       string                 // The raw token.  Populated when you Parse a token\n\tMethod    SigningMethod          // The signing method used or to be used\n\tHeader    map[string]interface{} // The first segment of the token\n\tClaims    Claims                 // The second segment of the token\n\tSignature string                 // The third segment of the token.  Populated when you Parse a token\n\tValid     bool                   // Is the token valid?  Populated when you Parse/Verify a token\n}\n\n// Create a new Token.  Takes a signing method\nfunc New(method SigningMethod) *Token {\n\treturn NewWithClaims(method, MapClaims{})\n}\n\nfunc NewWithClaims(method SigningMethod, claims Claims) *Token {\n\treturn &Token{\n\t\tHeader: map[string]interface{}{\n\t\t\t\"typ\": \"JWT\",\n\t\t\t\"alg\": method.Alg(),\n\t\t},\n\t\tClaims: claims,\n\t\tMethod: method,\n\t}\n}\n\n// Get the complete, signed token\nfunc (t *Token) SignedString(key interface{}) (string, error) {\n\tvar sig, sstr string\n\tvar err error\n\tif sstr, err = t.SigningString(); err != nil {\n\t\treturn \"\", err\n\t}\n\tif sig, err = t.Method.Sign(sstr, key); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.Join([]string{sstr, sig}, \".\"), nil\n}\n\n// Generate the signing string.  This is the\n// most expensive part of the whole deal.  Unless you\n// need this for something special, just go straight for\n// the SignedString.\nfunc (t *Token) SigningString() (string, error) {\n\tvar err error\n\tparts := make([]string, 2)\n\tfor i, _ := range parts {\n\t\tvar jsonValue []byte\n\t\tif i == 0 {\n\t\t\tif jsonValue, err = json.Marshal(t.Header); err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t} else {\n\t\t\tif jsonValue, err = json.Marshal(t.Claims); err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t}\n\n\t\tparts[i] = EncodeSegment(jsonValue)\n\t}\n\treturn strings.Join(parts, \".\"), nil\n}\n\n// Parse, validate, and return a token.\n// keyFunc will receive the parsed token and should return the key for validating.\n// If everything is kosher, err will be nil\nfunc Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {\n\treturn new(Parser).Parse(tokenString, keyFunc)\n}\n\nfunc ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {\n\treturn new(Parser).ParseWithClaims(tokenString, claims, keyFunc)\n}\n\n// Encode JWT specific base64url encoding with padding stripped\nfunc EncodeSegment(seg []byte) string {\n\treturn strings.TrimRight(base64.URLEncoding.EncodeToString(seg), \"=\")\n}\n\n// Decode JWT specific base64url encoding with padding stripped\nfunc DecodeSegment(seg string) ([]byte, error) {\n\tif l := len(seg) % 4; l > 0 {\n\t\tseg += strings.Repeat(\"=\", 4-l)\n\t}\n\n\treturn base64.URLEncoding.DecodeString(seg)\n}\n"
  }
]