From ffc2f001cc5783c93d8c0a87a3df02f18b7ba32a Mon Sep 17 00:00:00 2001 From: Cedric Staub Date: Thu, 23 Jul 2015 12:12:53 -0700 Subject: [PATCH] Fixes issue #40: extraneous zero padding on serialized exponent --- encoding.go | 23 +++++++++++++++++++++++ encoding_test.go | 12 ++++++++++++ jwk.go | 6 +----- jwk_test.go | 6 +++--- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/encoding.go b/encoding.go index 4927d298..7eaf829c 100644 --- a/encoding.go +++ b/encoding.go @@ -20,6 +20,7 @@ import ( "bytes" "compress/flate" "encoding/base64" + "encoding/binary" "encoding/json" "io" "math/big" @@ -131,6 +132,14 @@ func newBuffer(data []byte) *byteBuffer { } } +func newBufferFromInt(num uint64) *byteBuffer { + data := make([]byte, 8) + binary.BigEndian.PutUint64(data, num) + return &byteBuffer{ + data: data, + } +} + func (b *byteBuffer) MarshalJSON() ([]byte, error) { return json.Marshal(b.base64()) } @@ -175,3 +184,17 @@ func (b byteBuffer) bigInt() *big.Int { func (b byteBuffer) toInt() int { return int(b.bigInt().Int64()) } + +func (b byteBuffer) trim() *byteBuffer { + i := 0 + for _, b := range b.data { + if b == 0 { + i++ + } else { + break + } + } + return &byteBuffer{ + data: b.data[i:], + } +} diff --git a/encoding_test.go b/encoding_test.go index 8ab8e2f7..86c65eee 100644 --- a/encoding_test.go +++ b/encoding_test.go @@ -106,3 +106,15 @@ func TestInvalidCompression(t *testing.T) { t.Error("should not accept invalid data") } } + +func TestByteBufferTrim(t *testing.T) { + buf := newBufferFromInt(1).trim() + if len(buf.data) != 1 || buf.data[0] != 1 { + t.Error("Trimmed byte buffer for integer '1' should contain [0x01]") + } + + buf = newBufferFromInt(65537).trim() + if len(buf.data) != 3 || !bytes.Equal(buf.data, []byte{0x01, 0x00, 0x01}) { + t.Error("Trimmed byte buffer for integer '1' should contain [0x01, 0x00, 0x01]") + } +} diff --git a/jwk.go b/jwk.go index d90ff089..4be44945 100644 --- a/jwk.go +++ b/jwk.go @@ -20,7 +20,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rsa" - "encoding/binary" "encoding/json" "fmt" "math/big" @@ -128,13 +127,10 @@ func (key rawJsonWebKey) rsaPublicKey() (*rsa.PublicKey, error) { } func fromRsaPublicKey(pub *rsa.PublicKey) *rawJsonWebKey { - e := make([]byte, 4) - binary.BigEndian.PutUint32(e, uint32(pub.E)) - return &rawJsonWebKey{ Kty: "RSA", N: newBuffer(pub.N.Bytes()), - E: newBuffer(e), + E: newBufferFromInt(uint64(pub.E)).trim(), } } diff --git a/jwk_test.go b/jwk_test.go index 3831a7a8..3a89b85d 100644 --- a/jwk_test.go +++ b/jwk_test.go @@ -18,11 +18,11 @@ package jose import ( "bytes" - "fmt" - "encoding/json" "crypto/ecdsa" "crypto/elliptic" "crypto/rsa" + "encoding/json" + "fmt" "math/big" "reflect" "testing" @@ -178,7 +178,7 @@ func TestMarshalNonPointer(t *testing.T) { t.Error(fmt.Sprintf("Error marshalling JSON: %v", err)) return } - expected := "{\"Key\":{\"kty\":\"RSA\",\"n\":\"vd7rZIoTLEe-z1_8G1FcXSw9CQFEJgV4g9V277sER7yx5Qjz_Pkf2YVth6wwwFJEmzc0hoKY-MMYFNwBE4hQHw\",\"e\":\"AAEAAQ\"}}" + expected := "{\"Key\":{\"kty\":\"RSA\",\"n\":\"vd7rZIoTLEe-z1_8G1FcXSw9CQFEJgV4g9V277sER7yx5Qjz_Pkf2YVth6wwwFJEmzc0hoKY-MMYFNwBE4hQHw\",\"e\":\"AQAB\"}}" if string(out) != expected { t.Error("Failed to marshal embedded non-pointer JWK properly:", string(out)) }