go-jose icon indicating copy to clipboard operation
go-jose copied to clipboard

EdDSA key type inconsistency

Open kousu opened this issue 5 years ago • 4 comments

When EdDSA (i.e. ed25519) was added in https://github.com/square/go-jose/pull/154 / https://github.com/square/go-jose/issues/68, it made a choice that confuses me: the inner key type is ed25519.PrivateKey whereas for RSA and ECDSA it's *rsa.PrivateKey and *ecdsa.PrivateKey.

For example, this program loads a key from the command line and tells you what type it found, but it's written with everything as pointer types:

// ptrkey.go
package main

import (
	"io/ioutil"
	"os"

	"crypto/ecdsa"
	"crypto/rsa"
	"golang.org/x/crypto/ed25519"

	jose "gopkg.in/square/go-jose.v2"
)

func main() {

	keyBytes, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		panic(err)
	}

	var jwk jose.JSONWebKey
	err = jwk.UnmarshalJSON(keyBytes)
	if err != nil {
		panic(err)
	}

	key := jwk.Key

	switch key := key.(type) {
	case *ed25519.PrivateKey:
		println("ed25519")
	case *rsa.PrivateKey:
		println("RSA")
	case *ecdsa.PrivateKey:
		println("ECDSA")
	default:
		println("Unhandled key type for %s", key)
	}
}
$ jose-util generate-key --alg=PS256 --use=sig
$ go run ptrkey.go jwk-sig-*-priv.json 
RSA
$ rm -f *json

$ jose-util generate-key --alg=ES256 --use=sig
$ go run ptrkey.go jwk-sig-*-priv.json 
ECDSA
$ rm -f *json

$ jose-util generate-key --alg=EdDSA --use=sig
$ go run ptrkey.go jwk-sig-*-priv.json 
Unhandled key type for %s (0x116b040,0xc00000e100)

$ # but, removing the pointer with this patch

--- ptrkey.go	2019-06-26 17:57:55.000000000 -0400
+++ ptrkey2.go	2019-06-26 17:57:43.000000000 -0400
@@ -28,7 +28,7 @@
 	key := jwk.Key;
 
 	switch key := key.(type) {
-	case *ed25519.PrivateKey:
+	case ed25519.PrivateKey:
 			println("ed25519")
 	case *rsa.PrivateKey:
 			println("RSA")
@@ -37,4 +37,4 @@
 	default:
 		println("Unhandled key type for %s", key)
 	}
 }

gives

$ go run ptrkey.go jwk-sig-*-priv.json 
ed25519

What's up with that? Can the types be changed to be consistent, please?

kousu avatar Jun 26 '19 21:06 kousu

The ed25519.PublicKey and ed25519.PrivateKey types are both aliases for []byte, making them effectively already pointers. So it'd be an additional layer of indirection if they were to be handled as pointer types. That's not true for the other types, which are structs.

csstaub avatar Jun 27 '19 18:06 csstaub

What is the aim to not use the same format for all the keys? I say more, why there is no interface to abstract them? I'm making a dispatcher and I need to know the porpuse because I had the same doubt than @kousu. Is there any EDDSA example with Go-JOSE?

samu-gataca avatar Sep 12 '19 11:09 samu-gataca

@samu-gataca It's explained in my previous comment. What else do you need to know? I do have a refactor open for a v3 with an abstracted interface for keys to make this cleaner, but the v2 interface is what it is.

csstaub avatar Sep 12 '19 14:09 csstaub

@csstaub Have you any example using EdDSA with Go-JOSE?

I'm having some problems when I try to validate a JWT and obtain Claims. I always I'm receiving key/type incorrect. I achieve to generate the JWT but the problem is after that.

I'm using Keys generated by jose-utils.

samu-gataca avatar Sep 12 '19 16:09 samu-gataca