chore!: (untested) update to latest keypairs
This commit is contained in:
parent
6a22bfecc4
commit
499949ba52
|
@ -13,7 +13,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.coolaj86.com/coolaj86/go-mockid/mockid"
|
"git.coolaj86.com/coolaj86/go-mockid/mockid"
|
||||||
"git.coolaj86.com/coolaj86/go-mockid/xkeypairs"
|
|
||||||
"git.rootprojects.org/root/keypairs"
|
"git.rootprojects.org/root/keypairs"
|
||||||
|
|
||||||
_ "github.com/joho/godotenv/autoload"
|
_ "github.com/joho/godotenv/autoload"
|
||||||
|
@ -92,7 +91,7 @@ func main() {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// TODO privB := keypairs.MarshalJWKPrivateKey(privkey)
|
// TODO privB := keypairs.MarshalJWKPrivateKey(privkey)
|
||||||
privB := xkeypairs.MarshalJWKPrivateKey(privkey)
|
privB := keypairs.MarshalJWKPrivateKey(privkey)
|
||||||
fmt.Printf("Private Key:\n\t%s\n", string(privB))
|
fmt.Printf("Private Key:\n\t%s\n", string(privB))
|
||||||
pubB := keypairs.MarshalJWKPublicKey(keypairs.NewPublicKey(privkey.Public()))
|
pubB := keypairs.MarshalJWKPublicKey(keypairs.NewPublicKey(privkey.Public()))
|
||||||
fmt.Printf("Public Key:\n\t%s\n", string(pubB))
|
fmt.Printf("Public Key:\n\t%s\n", string(pubB))
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.coolaj86.com/coolaj86/go-mockid/xkeypairs"
|
"git.coolaj86.com/coolaj86/go-mockid/xkeypairs"
|
||||||
|
"git.rootprojects.org/root/keypairs"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -47,8 +48,8 @@ func getOpts(r *http.Request) (*xkeypairs.KeyOptions, error) {
|
||||||
Key: key,
|
Key: key,
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.Claims, _ = tok["claims"].(xkeypairs.Object)
|
opts.Claims, _ = tok["claims"].(keypairs.Object)
|
||||||
opts.Header, _ = tok["header"].(xkeypairs.Object)
|
opts.Header, _ = tok["header"].(keypairs.Object)
|
||||||
|
|
||||||
var n int
|
var n int
|
||||||
if 0 != seed {
|
if 0 != seed {
|
||||||
|
|
|
@ -45,7 +45,7 @@ func GeneratePrivateJWK(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
privkey := xkeypairs.GenPrivKey(opts)
|
privkey := xkeypairs.GenPrivKey(opts)
|
||||||
|
|
||||||
jwk := xkeypairs.MarshalJWKPrivateKey(privkey)
|
jwk := keypairs.MarshalJWKPrivateKey(privkey)
|
||||||
w.Write(append(jwk, '\n'))
|
w.Write(append(jwk, '\n'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ func GeneratePublicDER(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b, _ := xkeypairs.MarshalDERPublicKey(privkey.Public())
|
b, _ := keypairs.MarshalDERPublicKey(privkey.Public())
|
||||||
|
|
||||||
w.Write(b)
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ func GeneratePrivateDER(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
privkey := xkeypairs.GenPrivKey(opts)
|
privkey := xkeypairs.GenPrivKey(opts)
|
||||||
|
|
||||||
der, _ := xkeypairs.MarshalDERPrivateKey(privkey)
|
der, _ := keypairs.MarshalDERPrivateKey(privkey)
|
||||||
w.Write(der)
|
w.Write(der)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ func GeneratePublicPEM(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b, _ := xkeypairs.MarshalPEMPublicKey(privkey.Public())
|
b, _ := keypairs.MarshalPEMPublicKey(privkey.Public())
|
||||||
|
|
||||||
w.Write(b)
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ func GeneratePrivatePEM(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
privkey := xkeypairs.GenPrivKey(opts)
|
privkey := xkeypairs.GenPrivKey(opts)
|
||||||
|
|
||||||
privpem, _ := xkeypairs.MarshalPEMPrivateKey(privkey)
|
privpem, _ := keypairs.MarshalPEMPrivateKey(privkey)
|
||||||
w.Write(privpem)
|
w.Write(privpem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.coolaj86.com/coolaj86/go-mockid/xkeypairs"
|
"git.rootprojects.org/root/keypairs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignJWS will create an uncompressed JWT with the given payload
|
// SignJWS will create an uncompressed JWT with the given payload
|
||||||
|
@ -40,7 +40,7 @@ func sign(w http.ResponseWriter, r *http.Request, jwt bool) {
|
||||||
header["_seed"] = opts.Seed
|
header["_seed"] = opts.Seed
|
||||||
}
|
}
|
||||||
|
|
||||||
jws, err := xkeypairs.SignClaims(privkey, header, opts.Claims)
|
jws, err := keypairs.SignClaims(privkey, header, opts.Claims)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
@ -48,7 +48,7 @@ func sign(w http.ResponseWriter, r *http.Request, jwt bool) {
|
||||||
|
|
||||||
var b []byte
|
var b []byte
|
||||||
if jwt {
|
if jwt {
|
||||||
s := xkeypairs.JWSToJWT(jws)
|
s := keypairs.JWSToJWT(jws)
|
||||||
w.Write(append([]byte(s), '\n'))
|
w.Write(append([]byte(s), '\n'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.coolaj86.com/coolaj86/go-mockid/xkeypairs"
|
"git.rootprojects.org/root/keypairs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Verify will verify both JWT and uncompressed JWS
|
// Verify will verify both JWT and uncompressed JWS
|
||||||
|
@ -19,7 +19,7 @@ func Verify(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jws := &xkeypairs.JWS{}
|
jws := &keypairs.JWS{}
|
||||||
|
|
||||||
authzParts := strings.Split(r.Header.Get("Authorization"), " ")
|
authzParts := strings.Split(r.Header.Get("Authorization"), " ")
|
||||||
lenAuthz := len(authzParts)
|
lenAuthz := len(authzParts)
|
||||||
|
@ -75,16 +75,12 @@ func Verify(w http.ResponseWriter, r *http.Request) {
|
||||||
jws.Claims["exp"] = float64(time.Now().Add(5 * time.Minute).Unix())
|
jws.Claims["exp"] = float64(time.Now().Add(5 * time.Minute).Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := xkeypairs.VerifyClaims(nil, jws)
|
errs := keypairs.VerifyClaims(nil, jws)
|
||||||
if nil != err {
|
if 0 == len(errs) {
|
||||||
log.Printf("jws verify error: %s", err)
|
log.Printf("jws verify error: %s", errs)
|
||||||
http.Error(w, "Bad Request: could not verify JWS claims", http.StatusBadRequest)
|
http.Error(w, "Bad Request: could not verify JWS claims", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ok {
|
|
||||||
http.Error(w, "Bad Request: invalid JWS signature", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b := []byte(`{"success":true}`)
|
b := []byte(`{"success":true}`)
|
||||||
w.Write(append(b, '\n'))
|
w.Write(append(b, '\n'))
|
||||||
|
|
|
@ -66,11 +66,13 @@ type OTPResponse struct {
|
||||||
HTTPResponse
|
HTTPResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contact represents a map between an identifier and some users
|
||||||
type Contact struct {
|
type Contact struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Subjects []string `json:"subjects"`
|
Subjects []string `json:"subjects"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subject represents a map between a user and some identifiers
|
||||||
type Subject struct {
|
type Subject struct {
|
||||||
Subject string `json:"subject"`
|
Subject string `json:"subject"`
|
||||||
Emails map[string]time.Time `json:"emails"`
|
Emails map[string]time.Time `json:"emails"`
|
||||||
|
@ -109,7 +111,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
if nil != err {
|
if nil != err {
|
||||||
signingKey = xkeypairs.GenPrivKey(&xkeypairs.KeyOptions{})
|
signingKey = xkeypairs.GenPrivKey(&xkeypairs.KeyOptions{})
|
||||||
_ = os.MkdirAll(jwksPrefix+"/private", 0750)
|
_ = os.MkdirAll(jwksPrefix+"/private", 0750)
|
||||||
b := xkeypairs.MarshalJWKPrivateKey(signingKey)
|
b := keypairs.MarshalJWKPrivateKey(signingKey)
|
||||||
if err := ioutil.WriteFile(privKeyJWKPath, b, 0600); nil != err {
|
if err := ioutil.WriteFile(privKeyJWKPath, b, 0600); nil != err {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -320,10 +322,10 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
uuid, _ := uuid.NewRandom()
|
uuid, _ := uuid.NewRandom()
|
||||||
nonce, _ := uuid.MarshalBinary()
|
nonce, _ := uuid.MarshalBinary()
|
||||||
baseURL := getBaseURL(r)
|
baseURL := getBaseURL(r)
|
||||||
tok, err := xkeypairs.SignClaims(
|
tok, err := keypairs.SignClaims(
|
||||||
signingKey,
|
signingKey,
|
||||||
xkeypairs.Object{},
|
keypairs.Object{},
|
||||||
xkeypairs.Object{
|
keypairs.Object{
|
||||||
"sub": sub,
|
"sub": sub,
|
||||||
"iss": baseURL + "/",
|
"iss": baseURL + "/",
|
||||||
"jti": base64.RawURLEncoding.EncodeToString(nonce),
|
"jti": base64.RawURLEncoding.EncodeToString(nonce),
|
||||||
|
@ -336,7 +338,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
fmt.Fprintf(w, "%s", err)
|
fmt.Fprintf(w, "%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
otp.AccessToken = xkeypairs.JWSToJWT(tok)
|
otp.AccessToken = keypairs.JWSToJWT(tok)
|
||||||
b, _ := json.Marshal(&OTPResponse{
|
b, _ := json.Marshal(&OTPResponse{
|
||||||
HTTPResponse: HTTPResponse{Success: true},
|
HTTPResponse: HTTPResponse{Success: true},
|
||||||
OTP: *otp,
|
OTP: *otp,
|
||||||
|
@ -461,7 +463,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
http.HandleFunc("/api/new-account", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/api/new-account", func(w http.ResponseWriter, r *http.Request) {
|
||||||
myURL := getBaseURL(r) + r.URL.Path
|
myURL := getBaseURL(r) + r.URL.Path
|
||||||
|
|
||||||
jws := &xkeypairs.JWS{}
|
jws := &keypairs.JWS{}
|
||||||
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
if err := decoder.Decode(jws); nil != err {
|
if err := decoder.Decode(jws); nil != err {
|
||||||
|
@ -504,11 +506,8 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := xkeypairs.VerifyClaims(nil, jws)
|
errs := keypairs.VerifyClaims(nil, jws)
|
||||||
if nil != err || !ok {
|
if 0 != len(errs) {
|
||||||
if nil != err {
|
|
||||||
log.Printf("jws verify error: %s", err)
|
|
||||||
}
|
|
||||||
http.Error(w, "Bad Request", http.StatusBadRequest)
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
||||||
fmt.Fprintf(w, `{"error":"could not verify JWS claims"}`+"\n")
|
fmt.Fprintf(w, `{"error":"could not verify JWS claims"}`+"\n")
|
||||||
return
|
return
|
||||||
|
@ -530,7 +529,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
)
|
)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
http.Error(w, "Bad Request", http.StatusBadRequest)
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
||||||
msg, _ := json.Marshal(err.Error())
|
msg, _ := json.Marshal(err)
|
||||||
fmt.Fprintf(w, `{"error":%s}`+"\n", msg)
|
fmt.Fprintf(w, `{"error":%s}`+"\n", msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -684,7 +683,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) http.Handler {
|
||||||
|
|
||||||
http.HandleFunc("/key.jwk.json", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/key.jwk.json", func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("%s %s", r.Method, r.URL.Path)
|
log.Printf("%s %s", r.Method, r.URL.Path)
|
||||||
jwk := string(xkeypairs.MarshalJWKPrivateKey(privkey))
|
jwk := string(keypairs.MarshalJWKPrivateKey(privkey))
|
||||||
jwk = strings.Replace(jwk, `{"`, `{ "`, 1)
|
jwk = strings.Replace(jwk, `{"`, `{ "`, 1)
|
||||||
jwk = strings.Replace(jwk, `",`, `", `, -1)
|
jwk = strings.Replace(jwk, `",`, `", `, -1)
|
||||||
jwk = jwk[0 : len(jwk)-1]
|
jwk = jwk[0 : len(jwk)-1]
|
||||||
|
@ -816,6 +815,7 @@ func verifyToken(token string) (*InspectableToken, error) {
|
||||||
return inspected, nil
|
return inspected, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OTP is the one-time password for auth
|
||||||
type OTP struct {
|
type OTP struct {
|
||||||
//Attempts int `json:"attempts"`
|
//Attempts int `json:"attempts"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
|
|
@ -3,22 +3,30 @@ package xkeypairs
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
mathrand "math/rand"
|
||||||
|
|
||||||
"git.rootprojects.org/root/keypairs"
|
"git.rootprojects.org/root/keypairs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const maxRetry = 16
|
||||||
|
|
||||||
|
// RandomReader may be overwritten for testing
|
||||||
|
var RandomReader io.Reader = rand.Reader
|
||||||
|
|
||||||
|
//var RandomReader = rand.Reader
|
||||||
|
|
||||||
// KeyOptions are the things that we may need to know about a request to fulfill it properly
|
// KeyOptions are the things that we may need to know about a request to fulfill it properly
|
||||||
type KeyOptions struct {
|
type KeyOptions struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
KeyType string `json:"kty"`
|
KeyType string `json:"kty"`
|
||||||
Seed int64 `json:"-"`
|
Seed int64 `json:"-"`
|
||||||
SeedStr string `json:"seed"`
|
SeedStr string `json:"seed"`
|
||||||
Claims Object `json:"claims"`
|
Claims keypairs.Object `json:"claims"`
|
||||||
Header Object `json:"header"`
|
Header keypairs.Object `json:"header"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// this shananigans is only for testing and debug API stuff
|
// this shananigans is only for testing and debug API stuff
|
||||||
|
@ -26,7 +34,7 @@ func (o *KeyOptions) MyFooNextReader() io.Reader {
|
||||||
if 0 == o.Seed {
|
if 0 == o.Seed {
|
||||||
return RandomReader
|
return RandomReader
|
||||||
}
|
}
|
||||||
return rand.New(rand.NewSource(o.Seed))
|
return mathrand.New(mathrand.NewSource(o.Seed))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenPrivKey generates a 256-bit entropy RSA or ECDSA private key
|
// GenPrivKey generates a 256-bit entropy RSA or ECDSA private key
|
||||||
|
|
Loading…
Reference in New Issue