Skip to content

Instantly share code, notes, and snippets.

@kentquirk
Last active October 9, 2015 20:45
Show Gist options
  • Save kentquirk/7cc67eacb0fa98248fe0 to your computer and use it in GitHub Desktop.
Save kentquirk/7cc67eacb0fa98248fe0 to your computer and use it in GitHub Desktop.
decodeGoogleOAuthToken
// This file isn't really needed but I'm not ready to delete it yet.
package main
import (
"bytes"
"crypto"
"crypto/rsa"
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"math/big"
"net/http"
"strings"
"github.com/dgrijalva/jwt-go"
)
func (u *UserServer) unpackToken(token, secret string) (string, error) {
jwtToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { return []byte(secret), nil })
if err != nil {
fmt.Println(err)
return "", err
}
fmt.Println(jwtToken)
return "", nil
}
func decode(auth_token string) error {
w := strings.Split(auth_token, ".")
if len(w) < 3 {
return errors.New("invalid token")
}
jwtHdr, jwtBody, jwtSig := w[0], w[1], w[2]
if m := len(jwtHdr) % 4; m != 0 {
jwtHdr += strings.Repeat("=", 4-m)
}
if m := len(jwtSig) % 4; m != 0 {
jwtSig += strings.Repeat("=", 4-m)
}
headerOauth, err := base64.URLEncoding.DecodeString(jwtHdr)
fmt.Println(string(headerOauth))
bodyOauth, err := base64.URLEncoding.DecodeString(jwtBody)
fmt.Println(string(bodyOauth))
res, err := http.Get("https://www.googleapis.com/oauth2/v2/certs")
if err != nil {
fmt.Println(err)
return err
}
certs, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
fmt.Println(err)
return err
}
//extract kid from token header
var header interface{}
err = json.Unmarshal([]byte(string(headerOauth)), &header)
token_kid := header.(map[string]interface{})["kid"]
fmt.Println("By 1")
//get modulus and exponent from the cert
var goCertificate interface{}
err = json.Unmarshal(certs, &goCertificate)
//k := goCertificate.(map[string]interface{})[token_kid.(string)]
k := goCertificate.(map[string]interface{})["keys"]
///*mod & exp part
j := k.([]interface{})
x := j[0]
if j[0].(map[string]interface{})["kid"] == token_kid {
x = j[0]
} else {
if j[1].(map[string]interface{})["kid"] == token_kid {
x = j[1]
} else {
err = errors.New("Token is not valid, kid from token and certificate don't match")
return err
}
}
h := x.(map[string]interface{})["n"]
g := x.(map[string]interface{})["e"]
//build the google pub key
nStr := h.(string)
decN, err := base64.URLEncoding.DecodeString(nStr)
if err != nil {
fmt.Println(err)
return err
}
n := big.NewInt(0)
n.SetBytes(decN)
eStr := g.(string)
decE, err := base64.URLEncoding.DecodeString(eStr)
if err != nil {
fmt.Println(err)
return err
}
var eBytes []byte
if len(decE) < 8 {
eBytes = make([]byte, 8-len(decE), 8)
eBytes = append(eBytes, decE...)
} else {
eBytes = decE
}
eReader := bytes.NewReader(eBytes)
var e uint64
err = binary.Read(eReader, binary.BigEndian, &e)
if err != nil {
log.Println(err)
return err
}
pKey := rsa.PublicKey{N: n, E: int(e)}
//inblockOauth := base64.URLEncoding.DecodeString(w[1])
toHash := w[0] + "." + w[1]
digestOauth, err := base64.URLEncoding.DecodeString(jwtSig)
hasherOauth := sha256.New()
hasherOauth.Write([]byte(toHash))
// verification of the signature
err = rsa.VerifyPKCS1v15(&pKey, crypto.SHA256, hasherOauth.Sum(nil), digestOauth)
if err != nil {
fmt.Printf("Error verifying key %s", err.Error())
return err
}
fmt.Printf("OK!")
return nil
}
@kentquirk
Copy link
Author

This is code I wasn't using but maybe worth saving; some of it comes from somewhere else I don't remember - some oauth example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment