Skip to content

Commit

Permalink
refactor: Support JwsVerificationKey2020 for DID public key
Browse files Browse the repository at this point in the history
closes hyperledger-archives#1527, hyperledger-archives#1513

Signed-off-by: Dmitriy Kinoshenko <dkinoshenko@gmail.com>
  • Loading branch information
kdimak committed Mar 31, 2020
1 parent b14f446 commit ebf55eb
Show file tree
Hide file tree
Showing 7 changed files with 500 additions and 136 deletions.
80 changes: 57 additions & 23 deletions pkg/doc/did/doc.go
Expand Up @@ -112,7 +112,12 @@ type PublicKey struct {
ID string
Type string
Controller string
Value []byte

Value []byte

Algorithm string `json:"-"`
Curve string `json:"-"`
KeyType string `json:"-"`
}

// Service DID doc service
Expand Down Expand Up @@ -347,57 +352,83 @@ func populatePublicKeys(context string, rawPKs []map[string]interface{}) ([]Publ
var publicKeys []PublicKey

for _, rawPK := range rawPKs {
decodeValue, err := decodePK(rawPK)
if err != nil {
return nil, err
}

controllerKey := jsonldController

if context == contextV011 {
controllerKey = jsonldOwner
}

publicKeys = append(publicKeys, PublicKey{ID: stringEntry(rawPK[jsonldID]), Type: stringEntry(rawPK[jsonldType]),
Controller: stringEntry(rawPK[controllerKey]), Value: decodeValue})
publicKey := PublicKey{ID: stringEntry(rawPK[jsonldID]), Type: stringEntry(rawPK[jsonldType]),
Controller: stringEntry(rawPK[controllerKey])}

err := decodePK(&publicKey, rawPK)
if err != nil {
return nil, err
}

publicKeys = append(publicKeys, publicKey)
}

return publicKeys, nil
}

func decodePK(rawPK map[string]interface{}) ([]byte, error) {
func decodePK(publicKey *PublicKey, rawPK map[string]interface{}) error {
if stringEntry(rawPK[jsonldPublicKeyBase58]) != "" {
return base58.Decode(stringEntry(rawPK[jsonldPublicKeyBase58])), nil
publicKey.Value = base58.Decode(stringEntry(rawPK[jsonldPublicKeyBase58]))
return nil
}

if stringEntry(rawPK[jsonldPublicKeyHex]) != "" {
value, err := hex.DecodeString(stringEntry(rawPK[jsonldPublicKeyHex]))
if err != nil {
return nil, fmt.Errorf("decode public key hex failed: %w", err)
return fmt.Errorf("decode public key hex failed: %w", err)
}

return value, nil
publicKey.Value = value

return nil
}

if stringEntry(rawPK[jsonldPublicKeyPem]) != "" {
block, _ := pem.Decode([]byte(stringEntry(rawPK[jsonldPublicKeyPem])))
if block == nil {
return nil, errors.New("failed to decode PEM block containing public key")
return errors.New("failed to decode PEM block containing public key")
}

return block.Bytes, nil
publicKey.Value = block.Bytes

return nil
}

if jwkMap := mapEntry(rawPK[jsonldPublicKeyjwk]); jwkMap != nil {
jwkMap := mapEntry(rawPK[jsonldPublicKeyjwk])

jwkBytes, err := json.Marshal(jwkMap)
if err != nil {
return nil, fmt.Errorf("failed to marshal '%s', cause: %w ", jsonldPublicKeyjwk, err)
return fmt.Errorf("failed to marshal '%s', cause: %w ", jsonldPublicKeyjwk, err)
}

return jose.DecodePublicKey(jwkBytes)
var jwk jose.JWK

err = json.Unmarshal(jwkBytes, &jwk)
if err != nil {
return fmt.Errorf("unmarshal JWK: %w", err)
}

pkBytes, err := jwk.PublicKeyBytes()
if err != nil {
return fmt.Errorf("failed to decode public key from JWK: %w", err)
}

publicKey.Value = pkBytes
publicKey.Algorithm = jwk.Algorithm
publicKey.KeyType = jwk.Kty
publicKey.Curve = jwk.Crv

return nil
}

return nil, errors.New("public key encoding not supported")
return errors.New("public key encoding not supported")
}

func (r *rawDoc) ParseContext() []string {
Expand Down Expand Up @@ -583,8 +614,11 @@ func (r *didKeyResolver) Resolve(id string) (*verifier.PublicKey, error) {
for _, key := range r.PubKeys {
if key.ID == id {
return &verifier.PublicKey{
Type: key.Type,
Value: key.Value,
Type: key.Type,
Value: key.Value,
Curve: key.Curve,
Alg: key.Algorithm,
KeyType: key.KeyType,
}, nil
}
}
Expand Down Expand Up @@ -620,14 +654,14 @@ func populateRawServices(services []Service) []map[string]interface{} {

func populateRawPublicKeys(context string, pks []PublicKey) []map[string]interface{} {
var rawPKs []map[string]interface{}
for _, pk := range pks {
rawPKs = append(rawPKs, populateRawPublicKey(context, pk))
for i := range pks {
rawPKs = append(rawPKs, populateRawPublicKey(context, &pks[i]))
}

return rawPKs
}

func populateRawPublicKey(context string, pk PublicKey) map[string]interface{} {
func populateRawPublicKey(context string, pk *PublicKey) map[string]interface{} {
rawPK := make(map[string]interface{})
rawPK[jsonldID] = pk.ID
rawPK[jsonldType] = pk.Type
Expand All @@ -649,7 +683,7 @@ func populateRawAuthentications(context string, vms []VerificationMethod) []inte
var rawAuthentications []interface{}

for _, vm := range vms {
rawAuthentications = append(rawAuthentications, populateRawPublicKey(context, vm.PublicKey))
rawAuthentications = append(rawAuthentications, populateRawPublicKey(context, &vm.PublicKey))
}

return rawAuthentications
Expand Down

0 comments on commit ebf55eb

Please sign in to comment.