implement EC verify
This commit is contained in:
parent
d914325e2f
commit
563907d477
|
@ -1,6 +1,7 @@
|
||||||
package mockid
|
package mockid
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
@ -154,7 +155,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
protected64 := parts[0]
|
protected64 := parts[0]
|
||||||
data64 := parts[1]
|
payload64 := parts[1]
|
||||||
signature64 := parts[2]
|
signature64 := parts[2]
|
||||||
|
|
||||||
protectedB, err := base64.RawURLEncoding.DecodeString(protected64)
|
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)
|
http.Error(w, "Bad Format: token's header should be URL-safe base64 encoded", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dataB, err := base64.RawURLEncoding.DecodeString(data64)
|
payloadB, err := base64.RawURLEncoding.DecodeString(payload64)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
http.Error(w, "Bad Format: token's payload should be URL-safe base64 encoded", http.StatusBadRequest)
|
http.Error(w, "Bad Format: token's payload should be URL-safe base64 encoded", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO verify signature
|
// TODO verify signature
|
||||||
_, err = base64.RawURLEncoding.DecodeString(signature64)
|
sig, err := base64.RawURLEncoding.DecodeString(signature64)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
http.Error(w, "Bad Format: token's signature should be URL-safe base64 encoded", http.StatusBadRequest)
|
http.Error(w, "Bad Format: token's signature should be URL-safe base64 encoded", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
@ -190,7 +191,7 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
data := map[string]interface{}{}
|
data := map[string]interface{}{}
|
||||||
err = json.Unmarshal(dataB, &data)
|
err = json.Unmarshal(payloadB, &data)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
http.Error(w, "Bad Format: token's payload should be URL-safe base64-encoded JSON", http.StatusBadRequest)
|
http.Error(w, "Bad Format: token's payload should be URL-safe base64-encoded JSON", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
@ -208,12 +209,15 @@ func Route(jwksPrefix string, privkey keypairs.PrivateKey) {
|
||||||
fmt.Println("fetched pub key:")
|
fmt.Println("fetched pub key:")
|
||||||
fmt.Println(pub)
|
fmt.Println(pub)
|
||||||
|
|
||||||
|
hash := sha256.Sum256([]byte(fmt.Sprintf("%s.%s", protected64, payload64)))
|
||||||
|
verified := JOSEVerify(pub, hash[:], sig)
|
||||||
|
|
||||||
inspected := &InspectableToken{
|
inspected := &InspectableToken{
|
||||||
Public: pub,
|
Public: pub,
|
||||||
Protected: protected,
|
Protected: protected,
|
||||||
Payload: data,
|
Payload: data,
|
||||||
Signature: signature64,
|
Signature: signature64,
|
||||||
Verified: false,
|
Verified: verified,
|
||||||
Errors: errors,
|
Errors: errors,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,6 +514,31 @@ func GenToken(host string, privkey keypairs.PrivateKey, query url.Values) (strin
|
||||||
|
|
||||||
// TODO: move to keypairs
|
// 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 {
|
func JOSESign(privkey keypairs.PrivateKey, hash []byte) []byte {
|
||||||
var sig []byte
|
var sig []byte
|
||||||
|
|
||||||
|
@ -519,6 +548,8 @@ func JOSESign(privkey keypairs.PrivateKey, hash []byte) []byte {
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
r, s, _ := ecdsa.Sign(rand.Reader, k, hash[:])
|
r, s, _ := ecdsa.Sign(rand.Reader, k, hash[:])
|
||||||
rb := r.Bytes()
|
rb := r.Bytes()
|
||||||
|
fmt.Println("debug:")
|
||||||
|
fmt.Println(r, s)
|
||||||
for len(rb) < 32 {
|
for len(rb) < 32 {
|
||||||
rb = append([]byte{0}, rb...)
|
rb = append([]byte{0}, rb...)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue