grim/josetool
Clone
Summary
Browse
Changes
Graph
basic signing support. supports headers and claims but fails with ES256 right now, not sure why
draft
2017-02-07, Gary Kramlich
15ff42932e3c
Parents
ce2261105286
Children
b34b5deb7edd
basic signing support. supports headers and claims but fails with ES256 right now, not sure why
2 files changed, 108 insertions(+), 0 deletions(-)
+2
-0
main.go
+106
-0
sign.go
--- a/main.go Tue Feb 07 06:44:00 2017 +0000
+++ b/main.go Tue Feb 07 06:48:48 2017 +0000
@@ -19,6 +19,8 @@
err = genRSA()
case ecdsaCmd.FullCommand():
err = genECDSA()
+ case signCmd.FullCommand():
+ err = sign()
}
if err != nil {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sign.go Tue Feb 07 06:48:48 2017 +0000
@@ -0,0 +1,106 @@
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "strings"
+
+ "github.com/dgrijalva/jwt-go"
+ "github.com/mendsley/gojwk"
+)
+
+var (
+ signCmd = app.Command("sign", "creates a jwt for the given inputs")
+ signKey = signCmd.Arg("key", "the name of the file that contains the private jwk").Required().File()
+ signHeaders = signCmd.Flag("header", "header to include in the jwt in key=val format").Short('H').Strings()
+ signClaims = signCmd.Flag("claim", "claims to include in the jwt in key=val format").Short('c').Strings()
+
+ signingMap = map[string]jwt.SigningMethod{
+ "ES256": jwt.SigningMethodES256,
+ "ES384": jwt.SigningMethodES384,
+ "ES512": jwt.SigningMethodES512,
+ "RS256": jwt.SigningMethodRS256,
+ "RS384": jwt.SigningMethodRS384,
+ "RS512": jwt.SigningMethodES512,
+ }
+)
+
+func signGetClaims() (jwt.Claims, error) {
+ claims := jwt.MapClaims{}
+
+ for _, item := range *signClaims {
+ parts := strings.SplitN(item, "=", 2)
+ if len(parts) != 2 {
+ return nil, fmt.Errorf("invalid argument %v, must use key=val format", item)
+ }
+
+ claims[parts[0]] = parts[1]
+ }
+
+ return claims, nil
+}
+
+func signParseHeaders(headers map[string]interface{}) error {
+ for _, item := range *signHeaders {
+ parts := strings.SplitN(item, "=", 2)
+
+ if len(parts) != 2 {
+ return fmt.Errorf("invalid argument %v, must use key=val format")
+ }
+
+ headers[parts[0]] = parts[1]
+ }
+
+ return nil
+}
+
+func sign() error {
+ // read the file
+ data, err := ioutil.ReadAll(*signKey)
+ if err != nil {
+ return err
+ }
+
+ // unmarshal the jwk
+ key, err := gojwk.Unmarshal(data)
+ if err != nil {
+ return err
+ }
+
+ // make sure we know how to sign
+ signingMethod, found := signingMap[key.Alg]
+ if !found {
+ return fmt.Errorf("unknown algorithm %s", key.Alg)
+ }
+
+ // decode the private key from the jwk
+ priv, err := key.DecodePrivateKey()
+ if err != nil {
+ return err
+ }
+
+ // figure out the claims
+ claims, err := signGetClaims()
+ if err != nil {
+ return err
+ }
+
+ // generate the token
+ token := jwt.NewWithClaims(signingMethod, claims)
+
+ // now add the headers
+ err = signParseHeaders(token.Header)
+ if err != nil {
+ return err
+ }
+
+ // sign the data
+ str, err := token.SignedString(priv)
+ if err != nil {
+ return err
+ }
+
+ fmt.Printf("%s\n", str)
+
+ return nil
+}