From b01747d55d04ac4a43b6e5971659d2199d2cabb2 Mon Sep 17 00:00:00 2001 From: Kyle Boutette Date: Wed, 19 Sep 2018 22:33:51 +0000 Subject: [PATCH] Include precomputed RSA values in JSONWebKey.MarshallJSON Currently, go-jose doesn't copy over the pre-computed values(dp, dq, qi) if they exist on that key. https://github.com/square/go-jose/blob/v2.1.8/jwk.go#L488 This results in an incompatibility with node-jose. This is a rather difficult to debug issue given the opaque error node-jose generates, `unsupported algorithm`. https://github.com/square/go-jose/issues/202 --- jwk.go | 10 ++++++++++ jwk_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/jwk.go b/jwk.go index 8081d5ad..2dfd5d50 100644 --- a/jwk.go +++ b/jwk.go @@ -489,6 +489,16 @@ func fromRsaPrivateKey(rsa *rsa.PrivateKey) (*rawJSONWebKey, error) { raw.P = newBuffer(rsa.Primes[0].Bytes()) raw.Q = newBuffer(rsa.Primes[1].Bytes()) + if rsa.Precomputed.Dp != nil { + raw.Dp = newBuffer(rsa.Precomputed.Dp.Bytes()) + } + if rsa.Precomputed.Dq != nil { + raw.Dq = newBuffer(rsa.Precomputed.Dq.Bytes()) + } + if rsa.Precomputed.Qinv != nil { + raw.Qi = newBuffer(rsa.Precomputed.Qinv.Bytes()) + } + return raw, nil } diff --git a/jwk_test.go b/jwk_test.go index 27f986e9..359c1426 100644 --- a/jwk_test.go +++ b/jwk_test.go @@ -121,6 +121,42 @@ func TestRoundtripRsaPrivate(t *testing.T) { } } +func TestRoundtripRsaPrivatePrecomputed(t *testing.T) { + // Isolate a shallow copy of the rsaTestKey to avoid polluting it with Precompute + localKey := &(*rsaTestKey) + localKey.Precompute() + + jwk, err := fromRsaPrivateKey(localKey) + if err != nil { + t.Error("problem constructing JWK from rsa key", err) + } + + rsa2, err := jwk.rsaPrivateKey() + if err != nil { + t.Error("problem converting RSA private -> JWK", err) + } + + if rsa2.Precomputed.Dp == nil { + t.Error("RSA private Dp nil") + } + if rsa2.Precomputed.Dq == nil { + t.Error("RSA private Dq nil") + } + if rsa2.Precomputed.Qinv == nil { + t.Error("RSA private Qinv nil") + } + + if rsa2.Precomputed.Dp.Cmp(localKey.Precomputed.Dp) != 0 { + t.Error("RSA private Dp mismatch") + } + if rsa2.Precomputed.Dq.Cmp(localKey.Precomputed.Dq) != 0 { + t.Error("RSA private Dq mismatch") + } + if rsa2.Precomputed.Qinv.Cmp(localKey.Precomputed.Qinv) != 0 { + t.Error("RSA private Qinv mismatch") + } +} + func TestRsaPrivateInsufficientPrimes(t *testing.T) { brokenRsaPrivateKey := rsa.PrivateKey{ PublicKey: rsa.PublicKey{