-
-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement ability to handle PEM-formatted secp256k1 keys (#1117)
* Work with secp256k1 keys in PEM format * Add missing files * tweak bazel files * guard against go < 1.20 * protect the test from go < 1.20 * Fix import path * Override ParsePKCS8PrivateKey * Make this feature available through a separate build tag * Add lots of warnings about the feature * Add missing rules
- Loading branch information
Showing
10 changed files
with
663 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
//go:build jwx_es256k && jwx_secp256k1_pem && go1.20 | ||
|
||
package jwk_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/decred/dcrd/dcrec/secp256k1/v4" | ||
"github.com/lestrrat-go/jwx/v2/jwk" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestES256KPem(t *testing.T) { | ||
raw, err := secp256k1.GeneratePrivateKey() | ||
require.NoError(t, err, `GeneratePrivateKey should succeed`) | ||
|
||
testcases := []interface{}{raw.ToECDSA(), raw.PubKey().ToECDSA()} | ||
for _, tc := range testcases { | ||
t.Run(fmt.Sprintf("Marshal %T", tc), func(t *testing.T) { | ||
key, err := jwk.FromRaw(tc) | ||
require.NoError(t, err, `FromRaw should succeed`) | ||
|
||
pem, err := jwk.Pem(key) | ||
require.NoError(t, err, `Pem should succeed`) | ||
require.NotEmpty(t, pem, `Pem should not be empty`) | ||
|
||
parsed, err := jwk.Parse(pem, jwk.WithPEM(true)) | ||
require.NoError(t, err, `Parse should succeed`) | ||
_ = parsed | ||
}) | ||
} | ||
|
||
t.Run("ParsePKCS8PrivateKey", func(t *testing.T) { | ||
const src = `-----BEGIN PRIVATE KEY----- | ||
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQggS9t6iYyj9JSL+btkMEq | ||
pMYitWV4X+/Jg9zu3L8Ob5ShRANCAAT/YrxWHfw3e8lfDncJLLkPRbdby0L4qT95 | ||
vyWU5lPpSwRbEAfSFR1E5RD9irkN1mCY8D1ko1PAlmHVB78pNzq4 | ||
-----END PRIVATE KEY-----` | ||
key, err := jwk.Parse([]byte(src), jwk.WithPEM(true)) | ||
require.NoError(t, err, `Parse should succeed`) | ||
require.NotNil(t, key, `key should not be nil`) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") | ||
|
||
go_library( | ||
name = "x509", | ||
srcs = [ "x509.go", "x509_nosecp256k1.go", "x509_sepc256k1.go" ], | ||
importpath = "github.com/lestrrat-go/jwx/v2/jwk/internal/x509", | ||
visibility = ["//:__subpackages__"], | ||
) | ||
|
||
alias( | ||
name = "go_default_library", | ||
actual = ":x509", | ||
visibility = ["//jwe:__subpackages__"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package x509 | ||
|
||
import ( | ||
"crypto/rsa" | ||
"crypto/x509" | ||
) | ||
|
||
// In this x509 package we provide a proxy for crypto/x509 methods, | ||
// so that we can easily swap out the ParseECPrivateKey method with | ||
// our version of it that recognizes the secp256k1 curve... | ||
// _IF_ the jwx_es256k build tag is set. | ||
|
||
func MarshalPKCS1PrivateKey(priv *rsa.PrivateKey) []byte { | ||
return x509.MarshalPKCS1PrivateKey(priv) | ||
} | ||
|
||
func MarshalPKCS8PrivateKey(priv interface{}) ([]byte, error) { | ||
return x509.MarshalPKCS8PrivateKey(priv) | ||
} | ||
|
||
func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) { | ||
return x509.ParsePKCS1PrivateKey(der) | ||
} | ||
|
||
func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error) { | ||
return x509.ParsePKCS1PublicKey(der) | ||
} | ||
|
||
func ParseCertificate(der []byte) (*x509.Certificate, error) { | ||
return x509.ParseCertificate(der) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
//go:build !jwx_es256k || !jwx_secp256k1_pem || !go1.20 | ||
|
||
package x509 | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"crypto/x509" | ||
) | ||
|
||
func MarshalECPrivateKey(priv *ecdsa.PrivateKey) ([]byte, error) { | ||
return x509.MarshalECPrivateKey(priv) | ||
} | ||
|
||
func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) { | ||
return x509.ParseECPrivateKey(der) | ||
} | ||
|
||
func MarshalPKIXPublicKey(pub any) ([]byte, error) { | ||
return x509.MarshalPKIXPublicKey(pub) | ||
} | ||
|
||
func ParsePKIXPublicKey(der []byte) (any, error) { | ||
return x509.ParsePKIXPublicKey(der) | ||
} | ||
|
||
func ParsePKCS8PrivateKey(der []byte) (interface{}, error) { | ||
return x509.ParsePKCS8PrivateKey(der) | ||
} |
Oops, something went wrong.