From 563907d4774ad90b138ee10f789ad04071e8894c Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 11 May 2020 05:26:32 +0000 Subject: [PATCH] implement EC verify --- mockid/mockid.go | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/mockid/mockid.go b/mockid/mockid.go index b10b02c..98261a2 100644 --- a/mockid/mockid.go +++ b/mockid/mockid.go @@ -1,6 +1,7 @@ package mockid import ( + "crypto" "crypto/ecdsa" "crypto/rand" "crypto/rsa" @@ -154,7 +155,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) { return } protected64 := parts[0] - data64 := parts[1] + payload64 := parts[1] signature64 := parts[2] protectedB, err := base64.RawURLEncoding.DecodeString(protected64) @@ -162,13 +163,13 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) { http.Error(w, "Bad Format: token's header should be URL-safe base64 encoded", http.StatusBadRequest) return } - dataB, err := base64.RawURLEncoding.DecodeString(data64) + payloadB, err := base64.RawURLEncoding.DecodeString(payload64) if nil != err { http.Error(w, "Bad Format: token's payload should be URL-safe base64 encoded", http.StatusBadRequest) return } // TODO verify signature - _, err = base64.RawURLEncoding.DecodeString(signature64) + sig, err := base64.RawURLEncoding.DecodeString(signature64) if nil != err { http.Error(w, "Bad Format: token's signature should be URL-safe base64 encoded", http.StatusBadRequest) return @@ -190,7 +191,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) { } data := map[string]interface{}{} - err = json.Unmarshal(dataB, &data) + err = json.Unmarshal(payloadB, &data) if nil != err { http.Error(w, "Bad Format: token's payload should be URL-safe base64-encoded JSON", http.StatusBadRequest) return @@ -208,12 +209,15 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) { fmt.Println("fetched pub key:") fmt.Println(pub) + hash := sha256.Sum256([]byte(fmt.Sprintf("%s.%s", protected64, payload64))) + verified := JOSEVerify(pub, hash[:], sig) + inspected := &InspectableToken{ Public: pub, Protected: protected, Payload: data, Signature: signature64, - Verified: false, + Verified: verified, Errors: errors, } @@ -510,6 +514,31 @@ func GenToken(host string, privkey keypairs.PrivateKey, query url.Values) (strin // TODO: move to keypairs +func JOSEVerify(pubkey keypairs.PublicKey, hash []byte, sig []byte) bool { + var verified bool + + switch pub := pubkey.Key().(type) { + case *rsa.PublicKey: + // TODO keypairs.Size(key) to detect key size ? + //alg := "SHA256" + if err := rsa.VerifyPKCS1v15(pub, crypto.SHA256, hash, sig); nil != err { + verified = true + } + case *ecdsa.PublicKey: + r := &big.Int{} + r.SetBytes(sig[0:32]) + s := &big.Int{} + s.SetBytes(sig[32:]) + fmt.Println("debug: sig len:", len(sig)) + fmt.Println("debug: r, s:", r, s) + verified = ecdsa.Verify(pub, hash, r, s) + default: + panic("impossible condition: non-rsa/non-ecdsa key") + } + + return verified +} + func JOSESign(privkey keypairs.PrivateKey, hash []byte) []byte { var sig []byte @@ -519,6 +548,8 @@ func JOSESign(privkey keypairs.PrivateKey, hash []byte) []byte { case *ecdsa.PrivateKey: r, s, _ := ecdsa.Sign(rand.Reader, k, hash[:]) rb := r.Bytes() + fmt.Println("debug:") + fmt.Println(r, s) for len(rb) < 32 { rb = append([]byte{0}, rb...) }