implement EC verify

This commit is contained in:
AJ ONeal 2020-05-11 05:26:32 +00:00
parent d914325e2f
commit 563907d477
1 changed files with 36 additions and 5 deletions

View File

@ -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...)
}