Skip to content

Commit

Permalink
roundtrip tested
Browse files Browse the repository at this point in the history
  • Loading branch information
gabe committed Oct 16, 2023
1 parent 81d0c83 commit fe84aa0
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 11 deletions.
29 changes: 18 additions & 11 deletions impl/internal/did/did.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ func CreateDIDDHTDID(pubKey ed25519.PublicKey, opts CreateDIDDHTOpts) (*did.Docu

// validate opts and build verification methods, key purposes, and services
var vms []did.VerificationMethod
var keyAgreement []did.VerificationMethodSet
authentication := []did.VerificationMethodSet{"#0"}
assertionMethod := []did.VerificationMethodSet{"#0"}
keyAgreement := []did.VerificationMethodSet{"#0"}
capabilityInvocation := []did.VerificationMethodSet{"#0"}
capabilityDelegation := []did.VerificationMethodSet{"#0"}
if len(opts.VerificationMethods) > 0 {
Expand Down Expand Up @@ -107,27 +107,28 @@ func CreateDIDDHTDID(pubKey ed25519.PublicKey, opts CreateDIDDHTOpts) (*did.Docu
vms = append(vms, vm.VerificationMethod)

// add purposes
vmID := vm.VerificationMethod.ID[strings.LastIndex(vm.VerificationMethod.ID, "#"):]
for _, purpose := range vm.Purposes {
switch purpose {
case ion.Authentication:
authentication = append(authentication, vm.VerificationMethod.ID)
authentication = append(authentication, vmID)
case ion.AssertionMethod:
assertionMethod = append(assertionMethod, vm.VerificationMethod.ID)
assertionMethod = append(assertionMethod, vmID)
case ion.KeyAgreement:
keyAgreement = append(keyAgreement, vm.VerificationMethod.ID)
keyAgreement = append(keyAgreement, vmID)
case ion.CapabilityInvocation:
capabilityInvocation = append(capabilityInvocation, vm.VerificationMethod.ID)
capabilityInvocation = append(capabilityInvocation, vmID)
case ion.CapabilityDelegation:
capabilityDelegation = append(capabilityDelegation, vm.VerificationMethod.ID)
capabilityDelegation = append(capabilityDelegation, vmID)
default:
return nil, fmt.Errorf("unknown key purpose: %s:%s", vm.VerificationMethod.ID, purpose)
return nil, fmt.Errorf("unknown key purpose: %s:%s", vmID, purpose)
}
}
}
}
if len(opts.Services) > 0 {
seenIDs := make(map[string]bool)
for _, s := range opts.Services {
for i, s := range opts.Services {
if seenIDs[s.ID] {
return nil, fmt.Errorf("service id %s is not unique", s.ID)
}
Expand All @@ -136,7 +137,7 @@ func CreateDIDDHTDID(pubKey ed25519.PublicKey, opts CreateDIDDHTOpts) (*did.Docu
seenIDs[s.ID] = true

// update ID in place
s.ID = id + "#" + s.ID
opts.Services[i].ID = id + "#" + s.ID
}
}

Expand Down Expand Up @@ -178,7 +179,10 @@ func (d DHT) ToDNSPacket(doc did.Document) (*dns.Msg, error) {
var vmIDs []string
for i, vm := range doc.VerificationMethod {
recordIdentifier := fmt.Sprintf("k%d", i)
vmID := strings.Split(vm.ID, "#")[1]
vmID := vm.ID
if strings.Contains(vmID, "#") {
vmID = vmID[strings.LastIndex(vm.ID, "#")+1:]
}
keyLookup[vm.ID] = recordIdentifier

var keyType int
Expand Down Expand Up @@ -221,7 +225,10 @@ func (d DHT) ToDNSPacket(doc did.Document) (*dns.Msg, error) {
var svcIDs []string
for i, service := range doc.Services {
recordIdentifier := fmt.Sprintf("s%d", i)
sID := strings.Split("#", service.ID)[1]
sID := service.ID
if strings.Contains(sID, "#") {
sID = sID[strings.LastIndex(service.ID, "#")+1:]
}

serviceRecord := dns.TXT{
Hdr: dns.RR_Header{
Expand Down
82 changes: 82 additions & 0 deletions impl/internal/did/did_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,39 @@ func TestGenerateDIDDHT(t *testing.T) {
require.NoError(t, err)
require.NotEmpty(t, privKey)
require.NotEmpty(t, doc)

assert.NotEmpty(t, doc.ID)
assert.Empty(t, doc.Context)
assert.NotEmpty(t, doc.VerificationMethod)
assert.NotEmpty(t, doc.Authentication)
assert.NotEmpty(t, doc.AssertionMethod)
assert.Empty(t, doc.KeyAgreement)
assert.NotEmpty(t, doc.CapabilityDelegation)
assert.NotEmpty(t, doc.CapabilityInvocation)
assert.NotEmpty(t, doc.Services)

assert.Len(t, doc.VerificationMethod, 2)
assert.Len(t, doc.Authentication, 1)
assert.Len(t, doc.AssertionMethod, 2)
assert.Len(t, doc.KeyAgreement, 0)
assert.Len(t, doc.CapabilityDelegation, 1)
assert.Len(t, doc.CapabilityInvocation, 2)
assert.Len(t, doc.Services, 2)

assert.NotEmpty(t, doc.VerificationMethod[0].ID)
assert.EqualValues(t, doc.ID+"#0", doc.VerificationMethod[0].ID)
assert.NotEmpty(t, doc.VerificationMethod[0].Controller)
assert.Equal(t, doc.ID, doc.VerificationMethod[0].Controller)
assert.NotEmpty(t, doc.VerificationMethod[0].Type)
assert.NotEmpty(t, doc.VerificationMethod[0].PublicKeyJWK)

assert.Equal(t, doc.Services[0].ID, "did:dht:123456789abcdefghi#vcs")
assert.Equal(t, doc.Services[0].Type, "VerifiableCredentialService")
assert.Equal(t, doc.Services[0].ServiceEndpoint, "https://example.com/vc/")

assert.Equal(t, doc.Services[1].ID, "did:dht:123456789abcdefghi#hub")
assert.Equal(t, doc.Services[1].Type, "MessagingService")
assert.Equal(t, doc.Services[1].ServiceEndpoint, "https://example.com/hub/")
})
}

Expand All @@ -99,4 +132,53 @@ func TestToDNSPacket(t *testing.T) {

assert.EqualValues(t, *doc, *decodedDoc)
})

t.Run("doc with multiple keys and services - test to dns packet round trip", func(t *testing.T) {
pubKey, _, err := crypto.GenerateSECP256k1Key()
require.NoError(t, err)
pubKeyJWK, err := jwx.PublicKeyToPublicKeyJWK("key1", pubKey)
require.NoError(t, err)

opts := CreateDIDDHTOpts{
VerificationMethods: []VerificationMethod{
{
VerificationMethod: did.VerificationMethod{
ID: "key1",
Type: "JsonWebKey2020",
Controller: "did:dht:123456789abcdefghi",
PublicKeyJWK: pubKeyJWK,
},
Purposes: []ion.PublicKeyPurpose{ion.AssertionMethod, ion.CapabilityInvocation},
},
},
Services: []did.Service{
{
ID: "vcs",
Type: "VerifiableCredentialService",
ServiceEndpoint: "https://example.com/vc/",
},
{
ID: "hub",
Type: "MessagingService",
ServiceEndpoint: "https://example.com/hub/",
},
},
}
privKey, doc, err := GenerateDIDDHT(opts)
require.NoError(t, err)
require.NotEmpty(t, privKey)
require.NotEmpty(t, doc)

did := DHT(doc.ID)

packet, err := did.ToDNSPacket(*doc)
require.NoError(t, err)
require.NotEmpty(t, packet)

decodedDoc, err := did.FromDNSPacket(packet)
require.NoError(t, err)
require.NotEmpty(t, decodedDoc)

assert.EqualValues(t, *doc, *decodedDoc)
})
}

0 comments on commit fe84aa0

Please sign in to comment.