Skip to content

Commit

Permalink
feat: add rsa support for fingreprint (#18)
Browse files Browse the repository at this point in the history
* feat: add rsa support for fingreprint

* fix: cleanup

* fix: lint
  • Loading branch information
skynet2 authored Feb 15, 2024
1 parent 8dd4e25 commit 59c2830
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
17 changes: 16 additions & 1 deletion doc/util/fingerprint/fingerprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rsa"
"crypto/x509"
"encoding/binary"
"errors"
"fmt"
Expand All @@ -36,6 +38,9 @@ const (
// P521PubKeyMultiCodec for NIST P-521 public key in multicodec table.
P521PubKeyMultiCodec = 0x1202

// RSAPubKeyMultiCodec for RSA public key in multicodec table.
RSAPubKeyMultiCodec = 0x1205

// Default BLS 12-381 public key length in G2 field.
bls12381G2PublicKeyLen = 96

Expand All @@ -61,7 +66,7 @@ func CreateDIDKeyByCode(code uint64, pubKey []byte) (string, string) {

// CreateDIDKeyByJwk creates a did:key ID using the multicodec key fingerprint as per the did:key format spec found at:
// https://w3c-ccg.github.io/did-method-key/#format.
func CreateDIDKeyByJwk(jsonWebKey *jwk.JWK) (string, string, error) {
func CreateDIDKeyByJwk(jsonWebKey *jwk.JWK) (string, string, error) { //nolint:gocyclo
if jsonWebKey == nil {
return "", "", fmt.Errorf("jsonWebKey is required")
}
Expand Down Expand Up @@ -104,6 +109,16 @@ func CreateDIDKeyByJwk(jsonWebKey *jwk.JWK) (string, string, error) {
default:
return "", "", fmt.Errorf("unexpected OKP key type %T", key)
}
case "RSA":
key, ok := jsonWebKey.Key.(*rsa.PublicKey)
if !ok {
return "", "", fmt.Errorf("unexpected RSA key type %T", jsonWebKey.Key)
}

didKey, keyID := CreateDIDKeyByCode(RSAPubKeyMultiCodec, x509.MarshalPKCS1PublicKey(key))

return didKey, keyID, nil

default:
return "", "", fmt.Errorf("unsupported kty %s", jsonWebKey.Kty)
}
Expand Down
51 changes: 51 additions & 0 deletions doc/util/fingerprint/fingerprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"encoding/base64"
"fmt"
"math/big"
"strings"
"testing"

"github.com/btcsuite/btcutil/base58"
"github.com/go-jose/go-jose/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/trustbloc/kms-go/doc/jose/jwk"
Expand Down Expand Up @@ -303,6 +307,53 @@ func TestCreateDIDKeyByJwk(t *testing.T) {
})
}

func TestRSAFingerprint(t *testing.T) {
testKeys := []struct {
bitCount int
expectedPrefix string
}{
{
bitCount: 2048,
expectedPrefix: "did:key:z4MX",
},
{
bitCount: 4096,
expectedPrefix: "did:key:zgg",
},
}

for _, testKey := range testKeys {
t.Run(fmt.Sprint("RSA-", testKey.bitCount), func(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, testKey.bitCount)
require.NoError(t, err)

jwkKey, err := jwksupport.JWKFromKey(&key.PublicKey)
require.NoError(t, err)

didKey, keyID, err := CreateDIDKeyByJwk(jwkKey)
require.NoError(t, err)

assert.NotEmpty(t, didKey)
assert.NotEmpty(t, keyID)
assert.True(t, strings.HasPrefix(didKey, testKey.expectedPrefix))
})
}
}

func TestRSAInvalidKey(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
require.NoError(t, err)

jwkKey, err := jwksupport.JWKFromKey(&key.PublicKey)
require.NoError(t, err)

jwkKey.Key = "invalid key type"
didKey, keyID, err := CreateDIDKeyByJwk(jwkKey)
require.Empty(t, didKey)
require.Empty(t, keyID)
require.ErrorContains(t, err, "unexpected RSA key type string")
}

func TestDIDKeyEd25519(t *testing.T) {
const (
k1 = "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"
Expand Down

0 comments on commit 59c2830

Please sign in to comment.