package mockid import ( "crypto/ecdsa" "crypto/rsa" "encoding/base64" "fmt" "log" "math/big" "git.rootprojects.org/root/keypairs" ) // MarshalJWKPrivateKey outputs the given private key as JWK func MarshalJWKPrivateKey(privkey keypairs.PrivateKey) []byte { // thumbprint keys are alphabetically sorted and only include the necessary public parts switch k := privkey.(type) { case *rsa.PrivateKey: return MarshalRSAPrivateKey(k) case *ecdsa.PrivateKey: return MarshalECPrivateKey(k) default: // this is unreachable because we know the types that we pass in log.Printf("keytype: %t, %+v\n", privkey, privkey) panic(keypairs.ErrInvalidPublicKey) return nil } } // MarshalECPrivateKey will output the given private key as JWK func MarshalECPrivateKey(k *ecdsa.PrivateKey) []byte { crv := k.Curve.Params().Name d := base64.RawURLEncoding.EncodeToString(k.D.Bytes()) x := base64.RawURLEncoding.EncodeToString(k.X.Bytes()) y := base64.RawURLEncoding.EncodeToString(k.Y.Bytes()) return []byte(fmt.Sprintf( `{"crv":%q,"d":%q,"kty":"EC","x":%q,"y":%q}`, crv, d, x, y, )) } // MarshalRSAPrivateKey will output the given private key as JWK func MarshalRSAPrivateKey(pk *rsa.PrivateKey) []byte { e := base64.RawURLEncoding.EncodeToString(big.NewInt(int64(pk.E)).Bytes()) n := base64.RawURLEncoding.EncodeToString(pk.N.Bytes()) d := base64.RawURLEncoding.EncodeToString(pk.D.Bytes()) p := base64.RawURLEncoding.EncodeToString(pk.Primes[0].Bytes()) q := base64.RawURLEncoding.EncodeToString(pk.Primes[1].Bytes()) dp := base64.RawURLEncoding.EncodeToString(pk.Precomputed.Dp.Bytes()) dq := base64.RawURLEncoding.EncodeToString(pk.Precomputed.Dq.Bytes()) qi := base64.RawURLEncoding.EncodeToString(pk.Precomputed.Qinv.Bytes()) return []byte(fmt.Sprintf( `{"d":%q,"dp":%q,"dq":%q,"e":%q,"kty":"RSA","n":%q,"p":%q,"q":%q,"qi":%q}`, d, dp, dq, e, n, p, q, qi, )) }