Closed dhh1128 closed 4 years ago
I think this arises from a ledger focus without understanding what self-certifying means. It’s a common misconception that even those that should know better make as their focus is on preserving integrity of the did doc not preserving the root of trust in the origination of the identifier. The did doc is authoritative for events after origination but cannot be authoritative for origination itself. The genesis of the DID Doc is too late. It occurs after origination of the public/private key pair. The ledgerization attack is one example of what happens when the root of trust for origination is skipped. One reason for this misconception is that crypto textbooks (indeed much of crypto practice) assume that there is some authority that originates public private key pairs and therefore origination is a given. But this is inherently centralized. But in decentralized systems there is no UNIQUE origination authority. So its a bootstrap problem and self-certifying identifiers ( which are not mentioned in most crypto textbooks) elegantly solve the bootstrap origination authority problem by including the public key in the identifier. This means only the creator of the public key is uniquely able to certify as the origination authority via the associated private key and as importantly any entity may likewise be the only verifiable origination authority for any sufficiently collision resistant key pair they create ( assuming sufficient entropy for universal collision resistance). The authority is derived from the vanishingly small probability and any other entity could create the same public private key pair. Any namespacing (identifier) system that does not include the public key in the identifier opens new avenues of exploit because the identifier is no longer self-certifiable and hence dependent on some external origination authority and the linkage between that external origination of a public/private key pair and its association with the identifier is now open to exploit. Protecting the genesis of the DID Doc is too late. The origination event of the public private key pair and its association with the identifier is not protected.
The root of trust is that a public private key pair origination event when performed with a seed of sufficient entropy and a sufficiently strong digital signature cypher-suite is universally collision resistant. The origination event therefore unduplicatable and therefore self-authorizing.
To further elaborate. Much of modern PKI crypto assumes that users are incapable of managing their own private keys. This is still a widely held assumption by many expert practitioners in the field. As a result some external entity must therefore manage the key-pairs on the user’s behalf. This management authority may then create public-private keys pairs. This management authority derives its authority via the same self-authorizing capability of the public/private key pairs it creates. However it now may authoritatively associate those keys pairs with any identifier namespace it controls. The identifiers may not be self-certifying and don’t have to be because the managing entity has control over a namespace. Or a context that implies a namespace. It’s authority over the namespace allows it to make the association between public/private key pair and identifier. But now the managing authorities servers are a target of exploit. Making the managing authority a permissionless blockchain means that the association must be defined by an algorithm such as first to register. But even then participants (nodes and entities) derive their authority for participating from self-certifying identifiers (aka blockchain addresses which are encoded public keys from a public private keys pair). The root of trust in all decentralized systems is ultimately self-certifying identifiers derived from the public key of a public private key pair. Trying to mask this just gets us into trouble.
Sent from my iPad
On Sep 17, 2019, at 16:07, Daniel Hardman notifications@github.com wrote:
Originally, the peer DID spec required the peer DID value to be derived from "the public key". However, at IIW last spring, Christian Lundkvist convinced me that the did should derive from a hash of the genesis version of the DID Doc instead. Since that includes one or more public keys, it has much the same protections. But it doesn't have a protection against the abuse case I described in the preceding paragraph.
Relevant to this discussion is this white paper which discussion in detail key management for self-certifying identifiers. https://arxiv.org/abs/1907.02143. In this paper I define an inception event as the first event wherein the private key of a self-certifying identifier (namespace) is used. This inception event can be used to pre-rotate keys or any number of other operations As it is the first appearance of the public key (embedded in the identifier) and is signed by the associated private key it is authoritative for the event and is not subject to external exploit (exploits are limited to side channel attacks on the creation of the inception event itself).
Sent from my iPad
On Sep 17, 2019, at 16:07, Daniel Hardman notifications@github.com wrote:
A discussion thread on this vulnerability was started in the W3C CCG. Here's a quick summary of it for background:
@SmithSamuelM and I have been discussing an issue that I wanted to bring to this group. It is a risk that Sam has described as the "anybody can ledgerize" problem: What is to prevent someone other than the owner of a DID from recording the initial version of a DID doc on a ledger, thus making public something that the owner intended to keep off ledger for the time being or permanently?
Even though this question is framed in terms of ledgers, it has direct application to non-ledger DID methods as well.
I believe that some DID methods allow anyone with write permission or willing to pay transaction fees to write a DID and its initial DID Doc to the shared source of truth. Since the DID doc just contains public keys, all the info in it might be known by someone other than the DID's owner -- another party in the list of controllers, for example, or even an adversary. Yes, the adversary possesses none of the private keys, and so cannot control the DID after registration--but the mere registration of someone else's data could, in and of itself, constitute mischief.
To guard against abuse, the correct behavior of a ledger is probably to require that the request to write the genesis version of the DID doc be signed by a key in the DID doc. Note that just signing the DID doc isn't enough, since the attacker could have captured the signature when he captured the DID doc content. Even better security would be to require that the DID value be derived from a key in the DID doc, and that the initial write request use that key as well. Perhaps this protection against abuse needs to be a rubric? Or perhaps it is more fundamental, and needs to be a requirement of all DID methods, period?
Now I'd like to reason about how this applies to peer DIDs. Here's how it could play out there: Alice's agent 1 creates a DID doc for a relationship with Bob, naming keys for agent 2 and agent 3 as also authorized. Then Alice's agent 2 (which may have been hacked without Alice realizing it) can take that DID doc and send it to Carol, using the agent 2 key to sign. The rogue agent thus "registers" the DID doc in a way and with a party that the DID owner did not intend. This is basically the "anybody can ledgerize" attack.
Originally, the peer DID spec required the peer DID value to be derived from "the public key". However, at IIW last spring, Christian Lundkvist convinced me that the did should derive from a hash of the genesis version of the DID Doc instead. Since that includes one or more public keys, it has much the same protections. But it doesn't have a protection against the abuse case I described in the preceding paragraph.
At first glance, there seemed to be 3 possible answers:
Start the DID Doc with one public key; this is "the public key" from which the DID value derives, granting authority to all others. Require that the other 3 keys be added in subsequent operation(s).
Allow the DID Doc to be created with multiple keys, but make one of the keys special (e.g., the first key, or the key tagged as "prime" or some such); this is the one that must authorize creation.
Technique 1 might seem better from the perspective of self-certification purity, but it has a different cybersecurity problem, which is that such a strategy requires that you operate without checks and balances, and without backups, for some period of time early in the lifespan of every DID. We therefore discarded it; we wanted to be able to say, even in the genesis state, that a given DID is guarded by M-of-N signature policies, for example.
Right now the peer DID spec takes a weakened form of approach 2. It simply requires that the genesis DID doc be associated with (not necessarily signed by) one of the keys in its genesis state. Besides direct signing, "associated with" could mean that the genesis DID doc is streamed over DIDComm channels that authencrypt with one of the keys in question.
There is option 3:
We could require the genesis DID Doc to be signed by M-of-N agents if M-of-N agents are names as authorizers of subsequent edits. This eliminates the "anybody can ledgerize" risk, but it may be unacceptably inconvenient. I might create several keys that I store in vaults, offline, and that I never want to pull out when I'm creating new relationships--yet I might want to name those keys in the genesis versions of my pairwise DID Docs.
@SmithSamuelM suggested my current preferred option, which is to use pre-rotation. Basically we start a peer DID with only 1 key, and then we immediately create a delta that adds the other keys, before we even share the DID Doc at all. This is easily done and satisfies the convenience and strong security requirements. Its only drawback is that we need to modify the connection protocol (Aries RFC 0023) so it's possible to send a delta along with the initial version of a DID Doc that's exchanged when building a connection.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Sam: I think it's uncontroversial that we want the self-certifying property you've described so well, that our current method doesn't quite get there (because it allows for multiple keys in the genesis state), and would best be improved by using pre-rotation.
My only question is: how do we use pre-rotation while still preserving the characteristic that support for key rotation with peer DIDs is optional (layer 3), and without modifying the DID Exchange protocol (which allows a DID doc to be exchanged at the inception of a relationship, but does not allow deltas to accompany it).
If you have any ideas about answers to either of these questions, I'd be interested to hear them.
Daniel,
I am not sure I clearly understand the problem you are facing. I think if I understand, that if you are exchanging a did doc at the inception of a peer did relationship then the DID Doc thus exchanged could include a block that includes the key event receipts up to the creation of the DID Doc. Usually this would be just the inception and one rotation of the identifier. But it could include any number of rotations. These rotations are not deltas on the DID Doc but establish via verification of the receipts the current authoritative key(s) for the identifier and hence theDID Doc origination as provided. In other words the DID DOC origination event is not the inception event for the identifier. The DID Doc origination event includes the DID Doc and key event history receipts for the rotation(s) as well as signatures on the DID doc itself using the current (as established by the key event receipts) authoritative keys. This would make the verification of the DID Doc self contained and hence appropriate for a pair wise private relationship.
The concept is to decouple or remove the DID DOC as the primary source of the key event state (replace that with much more compact key event receipts) and then the DID Doc becomes a snapshot of the key event state by including the key event receipt log and signatures of the did doc with the current authorities keys. For non peer DIDs the DID Doc would include a designation of the infrastructure that provides the key event state. But for peer DIDs it needs to be self contained. In the KERI parlance the DID DOC is an interaction event not a key event. This approach is generalizable to any protocol and could also be used to support the delegated credentials you so wonderfully described today.
In KERI the fundamental unit of information is an event and a signed event is a receipt. The events are chained thereby establishing provenance of state.
The weakness of using theDID DOC as the primary source of truth for authoritative keys is that the did doc does too much (not merely limited to key event state) and may occur after inception. The best use of the DID doc is for discovery and indirection via methods or service endpoints and not being the primary source of truth for key event state. It’s ok as a snapshot of key event state but better to use its indirection to determine key event state. This is what is happening anyway.
It seems to me that a weakness of VC in general is that key event (rotation) state is not a first order property of the credential. By decoupling the maintenance of key event (rotation) state from the transaction/interaction event (VC for example) the key event state becomes separable manageable. This allows VC to be issued and revoked without requiring a revocation ledger which would be most useful for delegated credentials.
If you read the description of Pair-Wise KERI it solves the problem of provenance for key state for pair wise interactions without resort to any external infra-structure. So it could work for Peer DIDs. In this case the “DID Doc” does not ever need to be registered with a resolver (other than a local one for each of the pair wise parties) and what your are calling a DID Doc, KERI would call a special type of interaction event. Because all events (both key and interaction) are chained there is no additional effort to support Did Doc deltas they would just happen in stride with all other events exchanged between the two parties and all rooted to the same key event receipt log and state.
The way I see things the most fundamental problem to be solved is the key management of the authoritative keys for a self-certifying identifier. Once that infrastructure is in place all the other transactions can be more simply built on that foundation where the root of trust is always established and provenanced as a first order property of the infrastructure not a bolt on.
The intent of this approach is to preclude many of the thornier problems as we try to expand functionality they will never come up because they have already been solved by operating on a firm root of trust. The DID Doc idea was a good idea for lots of reasons but tries to do too much to be that firm root of trust. We see this in side-tree and all the ledger based solutions for key management. But these ledger based solutions do not solve the ephemeral or private DID problem. KERI was designed to be universal and especially works for ephemeral DIDs.
Sent from my iPad
On Sep 18, 2019, at 14:46, Daniel Hardman notifications@github.com wrote:
Sam: I think it's uncontroversial that we want the self-certifying property you've described so well, that our current method doesn't quite get there (because it allows for multiple keys in the genesis state), and would best be improved by using pre-rotation.
My only question is: how do we use pre-rotation while still preserving the characteristic that support for key rotation with peer DIDs is optional (layer 3), and without modifying the DID Exchange protocol (which allows a DID doc to be exchanged at the inception of a relationship, but does not allow deltas to accompany it).
If you have any ideas about answers to either of these questions, I'd be interested to hear them.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Daniel,
To clarify. I am not suggesting that to solve your problem you use KERI per se but include in the DID Doc the equivalent of a KERI key event receipt log to establish the authoritative keys (key state) for the identifier at Did Doc origination. This can be self contained.
Mentally it may seem odd if one’s orientation is that key state deltas require did doc deltas. I am saying that in private relationships the key state of each party may be more simply maintained by that party via a local key event receipt log that may be conveyed or shared as a batch to the other party via a did doc if that is what is needed to ensure DID method compatibility. The KERI approach is DID method agnostic (indeed any self certifying identifier class) one need merely take snapshots to make it compatible with more course grained key management.
Sent from my iPad
On Sep 18, 2019, at 16:00, Samuel Smith smithsamuelm@gmail.com wrote:
Daniel,
I am not sure I clearly understand the problem you are facing. I think if I understand, that if you are exchanging a did doc at the inception of a peer did relationship then the DID Doc thus exchanged could include a block that includes the key event receipts up to the creation of the DID Doc. Usually this would be just the inception and one rotation of the identifier. But it could include any number of rotations. These rotations are not deltas on the DID Doc but establish via verification of the receipts the current authoritative key(s) for the identifier and hence theDID Doc origination as provided. In other words the DID DOC origination event is not the inception event for the identifier. The DID Doc origination event includes the DID Doc and key event history receipts for the rotation(s) as well as signatures on the DID doc itself using the current (as established by the key event receipts) authoritative keys. This would make the verification of the DID Doc self contained and hence appropriate for a pair wise private relationship.
The concept is to decouple or remove the DID DOC as the primary source of the key event state (replace that with much more compact key event receipts) and then the DID Doc becomes a snapshot of the key event state by including the key event receipt log and signatures of the did doc with the current authorities keys. For non peer DIDs the DID Doc would include a designation of the infrastructure that provides the key event state. But for peer DIDs it needs to be self contained. In the KERI parlance the DID DOC is an interaction event not a key event. This approach is generalizable to any protocol and could also be used to support the delegated credentials you so wonderfully described today.
In KERI the fundamental unit of information is an event and a signed event is a receipt. The events are chained thereby establishing provenance of state.
The weakness of using theDID DOC as the primary source of truth for authoritative keys is that the did doc does too much (not merely limited to key event state) and may occur after inception. The best use of the DID doc is for discovery and indirection via methods or service endpoints and not being the primary source of truth for key event state. It’s ok as a snapshot of key event state but better to use its indirection to determine key event state. This is what is happening anyway.
It seems to me that a weakness of VC in general is that key event (rotation) state is not a first order property of the credential. By decoupling the maintenance of key event (rotation) state from the transaction/interaction event (VC for example) the key event state becomes separable manageable. This allows VC to be issued and revoked without requiring a revocation ledger which would be most useful for delegated credentials.
If you read the description of Pair-Wise KERI it solves the problem of provenance for key state for pair wise interactions without resort to any external infra-structure. So it could work for Peer DIDs. In this case the “DID Doc” does not ever need to be registered with a resolver (other than a local one for each of the pair wise parties) and what your are calling a DID Doc, KERI would call a special type of interaction event. Because all events (both key and interaction) are chained there is no additional effort to support Did Doc deltas they would just happen in stride with all other events exchanged between the two parties and all rooted to the same key event receipt log and state.
The way I see things the most fundamental problem to be solved is the key management of the authoritative keys for a self-certifying identifier. Once that infrastructure is in place all the other transactions can be more simply built on that foundation where the root of trust is always established and provenanced as a first order property of the infrastructure not a bolt on.
The intent of this approach is to preclude many of the thornier problems as we try to expand functionality they will never come up because they have already been solved by operating on a firm root of trust. The DID Doc idea was a good idea for lots of reasons but tries to do too much to be that firm root of trust. We see this in side-tree and all the ledger based solutions for key management. But these ledger based solutions do not solve the ephemeral or private DID problem. KERI was designed to be universal and especially works for ephemeral DIDs.
Sent from my iPad
On Sep 18, 2019, at 14:46, Daniel Hardman notifications@github.com wrote:
Sam: I think it's uncontroversial that we want the self-certifying property you've described so well, that our current method doesn't quite get there (because it allows for multiple keys in the genesis state), and would best be improved by using pre-rotation.
My only question is: how do we use pre-rotation while still preserving the characteristic that support for key rotation with peer DIDs is optional (layer 3), and without modifying the DID Exchange protocol (which allows a DID doc to be exchanged at the inception of a relationship, but does not allow deltas to accompany it).
If you have any ideas about answers to either of these questions, I'd be interested to hear them.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Closing this issue because we've moved the repo and we've determined to reframe peer DIDs in terms of KERI. This will naturally cause us to resolve the concern here. Therefore, work on this issue can take place in the context of https://github.com/decentralized-identity/peer-did-method-spec/issues/4.
A discussion thread on this vulnerability was started in the W3C CCG. Here's a quick summary of it for background:
Now I'd like to reason about how this applies to peer DIDs. Here's how it could play out there: Alice's agent 1 creates a DID doc for a relationship with Bob, naming keys for agent 2 and agent 3 as also authorized. Then Alice's agent 2 (which may have been hacked without Alice realizing it) can take that DID doc and send it to Carol, using the agent 2 key to sign. The rogue agent thus "registers" the DID doc in a way and with a party that the DID owner did not intend. This is basically the "anybody can ledgerize" attack.
Originally, the peer DID spec required the peer DID value to be derived from "the public key". However, at IIW last spring, Christian Lundkvist convinced me that the did should derive from a hash of the genesis version of the DID Doc instead. Since that includes one or more public keys, it has much the same protections. But it doesn't have a protection against the abuse case I described in the preceding paragraph.
At first glance, there seemed to be 3 possible answers:
Start the DID Doc with one public key; this is "the public key" from which the DID value derives, granting authority to all others. Require that the other 3 keys be added in subsequent operation(s).
Allow the DID Doc to be created with multiple keys, but make one of the keys special (e.g., the first key, or the key tagged as "prime" or some such); this is the one that must authorize creation.
Technique 1 might seem better from the perspective of self-certification purity, but it has a different cybersecurity problem, which is that such a strategy requires that you operate without checks and balances, and without backups, for some period of time early in the lifespan of every DID. We therefore discarded it; we wanted to be able to say, even in the genesis state, that a given DID is guarded by M-of-N signature policies, for example.
Right now the peer DID spec takes a weakened form of approach 2. It simply requires that the genesis DID doc be associated with (not necessarily signed by) one of the keys in its genesis state. Besides direct signing, "associated with" could mean that the genesis DID doc is streamed over DIDComm channels that authencrypt with one of the keys in question.
There is option 3:
This eliminates the "anybody can ledgerize" risk, but it may be unacceptably inconvenient. I might create several keys that I store in vaults, offline, and that I never want to pull out when I'm creating new relationships--yet I might want to name those keys in the genesis versions of my pairwise DID Docs.
@SmithSamuelM suggested my current preferred option, which is to use pre-rotation. Basically we start a peer DID with only 1 key, and then we immediately create a delta that adds the other keys, before we even share the DID Doc at all. This is easily done and satisfies the convenience and strong security requirements. Its only drawback is that we need to modify the connection protocol (Aries RFC 0023) so it's possible to send a delta along with the initial version of a DID Doc that's exchanged when building a connection.