// ReadPrivateKeyFromPEM is a helper function for reading a private key from a PEM-encoded file func ReadPrivateKeyFromPEM(data []byte) (interface{}, error) { if key, err := jwt.ParseRSAPrivateKeyFromPEM(data); err == nil { return key, nil } if key, err := jwt.ParseECPrivateKeyFromPEM(data); err == nil { return key, nil } return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key") }
// Create, sign, and output a token. This is a great, simple example of // how to use this library to create and sign a token. func signToken() error { // get the token data from command line arguments tokData, err := loadData(*flagSign) if err != nil { return fmt.Errorf("Couldn't read token: %v", err) } else if *flagDebug { fmt.Fprintf(os.Stderr, "Token: %v bytes", len(tokData)) } // parse the JSON of the claims var claims map[string]interface{} if err := json.Unmarshal(tokData, &claims); err != nil { return fmt.Errorf("Couldn't parse claims JSON: %v", err) } // get the key var key interface{} key, err = loadData(*flagKey) if err != nil { return fmt.Errorf("Couldn't read key: %v", err) } // get the signing alg alg := jwt.GetSigningMethod(*flagAlg) if alg == nil { return fmt.Errorf("Couldn't find signing method: %v", *flagAlg) } // create a new token token := jwt.New(alg) token.Claims = claims if isEs() { if k, ok := key.([]byte); !ok { return fmt.Errorf("Couldn't convert key data to key") } else { key, err = jwt.ParseECPrivateKeyFromPEM(k) if err != nil { return err } } } if out, err := token.SignedString(key); err == nil { fmt.Println(out) } else { return fmt.Errorf("Error signing token: %v", err) } return nil }
// DecodePrivateKey pulls the private key out of the string passed by first // decoding from base64 and parsing the PEM encoding. func DecodePrivateKey(privateKeyBase64Str string) (*ecdsa.PrivateKey, error) { // Our private key has been encoded from a PEM encoded private ECDSA key into this // privateKeyBase64Str. We need to decode the base64 string in order to get the // PEM encoded certificate back out. privateKeyPEM, err := base64.StdEncoding.DecodeString(privateKeyBase64Str) if err != nil { return nil, err } // Now that we have our PEM encoded private ECDSA key, we can parse it using the // methods built into the jwt librairy into something we can use to verify the // incomming JWT's. privateKey, err := jwt.ParseECPrivateKeyFromPEM(privateKeyPEM) if err != nil { return nil, err } return privateKey, nil }
// ReadPublicKeysFromPEM is a helper function for reading an array of rsa.PublicKey or ecdsa.PublicKey from a PEM-encoded byte array. // Reads public keys from both public and private key files. func ReadPublicKeysFromPEM(data []byte) ([]interface{}, error) { var block *pem.Block keys := []interface{}{} for { // read the next block block, data = pem.Decode(data) if block == nil { break } // get PEM bytes for just this block blockData := pem.EncodeToMemory(block) if privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(blockData); err == nil { keys = append(keys, &privateKey.PublicKey) continue } if publicKey, err := jwt.ParseRSAPublicKeyFromPEM(blockData); err == nil { keys = append(keys, publicKey) continue } if privateKey, err := jwt.ParseECPrivateKeyFromPEM(blockData); err == nil { keys = append(keys, &privateKey.PublicKey) continue } if publicKey, err := jwt.ParseECPublicKeyFromPEM(blockData); err == nil { keys = append(keys, publicKey) continue } // tolerate non-key PEM blocks for backwards compatibility // originally, only the first PEM block was parsed and expected to be a key block } if len(keys) == 0 { return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA key") } return keys, nil }