Adds receiver side of sync flow to ID docs. Cleanup.

This commit is contained in:
Joel Dudley 2017-10-23 10:24:36 +01:00 committed by GitHub
parent 5cd6f61a7f
commit 3a69f2a60c
2 changed files with 90 additions and 71 deletions

View File

@ -7,61 +7,59 @@ API: Identity
Party Party
----- -----
Identities on the network are represented by ``AbstractParty``. There are two types of ``AbstractParty``: Parties on the network are represented using the ``AbstractParty`` class. There are two types of ``AbstractParty``:
* ``Party``, identified by a ``PublicKey`` and a ``CordaX500Name`` * ``Party``, identified by a ``PublicKey`` and a ``CordaX500Name``
* ``AnonymousParty``, identified by a ``PublicKey`` only
* ``AnonymousParty``, identified by a ``PublicKey`` Using ``AnonymousParty`` to identify parties in states and commands prevents nodes from learning the identities
of the parties involved in a transaction when they verify the transaction's dependency chain. When preserving the
anonymity of each party is not required (e.g. for internal processing), ``Party`` can be used instead.
For example, in a transaction sent to your node as part of a chain of custody it is important you can convince yourself The identity service allows flows to resolve ``AnonymousParty`` to ``Party``, but only if the anonymous party's
of the transaction's validity, but equally important that you don't learn anything about who was involved in that identity has already been registered with the node (typically handled by ``SwapIdentitiesFlow`` or
transaction. In these cases ``AnonymousParty`` should be used by flows constructing when transaction states and commands. ``IdentitySyncFlow``, discussed below).
In contrast, for internal processing where extended details of a party are required, the ``Party`` class should be used
instead. The identity service provides functionality for flows to resolve anonymous parties to full parties, dependent
on the anonymous party's identity having been registered with the node earlier (typically this is handled by
``SwapIdentitiesFlow`` or ``IdentitySyncFlow``, discussed below).
Party names are held within the ``CordaX500Name`` data class, which enforces the structure of names within Corda, as Party names use the ``CordaX500Name`` data class, which enforces the structure of names within Corda, as well as
well as ensuring a consistent rendering of the names in plain text. ensuring a consistent rendering of the names in plain text.
The support for both Party and AnonymousParty classes in Corda enables sophisticated selective disclosure of identity Support for both ``Party`` and ``AnonymousParty`` classes in Corda enables sophisticated selective disclosure of
information. For example, it is possible to construct a Transaction using an AnonymousParty, so nobody can learn of your identity information. For example, it is possible to construct a transaction using an ``AnonymousParty`` (so nobody can
involvement by inspection of the transaction, yet prove to specific counterparts that this AnonymousParty actually is learn of your involvement by inspection of the transaction), yet prove to specific counterparts that this
owned by your well known identity. This disclosure is achieved through the use of the PartyAndCertificate data class ``AnonymousParty`` actually corresponds to your well-known identity. This is achieved using the
which can be propagated to those who need to know, and contains the Party's X.509 certificate path to provide proof of ``PartyAndCertificate`` data class, which contains the X.509 certificate path proving that a given ``AnonymousParty``
ownership by a well known identity. corresponds to a given ``Party``. Each ``PartyAndCertificate`` can be propagated to counterparties on a need-to-know
basis.
The PartyAndCertificate class is also used in the network map service to represent well known identities, in which The ``PartyAndCertificate`` class is also used by the network map service to represent well-known identities, with the
scenario the certificate path proves its issuance by the Doorman service. certificate path proving the certificate was issued by the doorman service.
Confidential identities
Confidential Identities
----------------------- -----------------------
Confidential identities are key pairs where the corresponding X.509 certificate (and path) are not made public, so that
Confidential identities are key pairs where the corresponding X.509 certificate (and path) are not made public, so that parties who parties who are not involved in the transaction cannot identify the owner. They are owned by a well-known identity,
are not involved in the transaction cannot identify its participants. They are owned by a well known identity, which which must sign the X.509 certificate. Before constructing a new transaction the involved parties must generate and
must sign the X.509 certificate. Before constructing a new transaction the involved parties must generate and send new exchange new confidential identities, a process which is managed using ``SwapIdentitiesFlow`` (discussed below). The
confidential identities to each other, a process which is managed using ``SwapIdentitiesFlow`` (discussed below). The public keys of these confidential identities are then used when generating output states and commands for the
public keys of these confidential identities are then used when generating output states and commands for the transaction. transaction.
Where using outputs from a previous transaction in a new transaction, counterparties may need to know who the involved Where using outputs from a previous transaction in a new transaction, counterparties may need to know who the involved
parties are. One example is in ``TwoPartyTradeFlow`` which delegates to ``CollectSignaturesFlow`` to gather certificates parties are. One example is the ``TwoPartyTradeFlow``, where an existing asset is exchanged for cash. If confidential
from both parties. ``CollectSignaturesFlow`` requires that a confidential identity of the initiating node has signed identities are being used, the buyer will want to ensure that the asset being transferred is owned by the seller, and
the transaction, and verifying this requires the receiving node has a copy of the confidential identity for the input the seller will likewise want to ensure that the cash being transferred is owned by the buyer. Verifying this requires
state. ``IdentitySyncFlow`` can be used to synchronize the confidential identities we have the certificate paths for, in both nodes to have a copy of the confidential identities for the asset and cash input states. ``IdentitySyncFlow``
a single transaction, to another node. manages this process. It takes as inputs a transaction and a counterparty, and for every confidential identity involved
in that transaction for which the calling node holds the certificate path, it sends this certificate path to the
counterparty.
.. note:: ``CollectSignaturesFlow`` requires that the initiating node has signed the transaction, and as such all nodes SwapIdentitiesFlow
providing signatures must recognise the signing key used by the initiating node as being either its well known identity ~~~~~~~~~~~~~~~~~~
or a confidential identity they have the certificate for. ``SwapIdentitiesFlow`` is typically run as a subflow of another flow. It takes as its sole constructor argument the
counterparty we want to exchange confidential identities with. It returns a mapping from the identities of the caller
and the counterparty to their new confidential identities. In the future, this flow will be extended to handle swapping
identities with multiple parties at once.
Swap identities flow You can see an example of using ``SwapIdentitiesFlow`` in ``TwoPartyDealFlow.kt``:
~~~~~~~~~~~~~~~~~~~~
``SwapIdentitiesFlow`` takes the party to swap identities with in its constructor (the counterparty), and is typically run as a subflow of
another flow. It returns a mapping from well known identities of the calling flow and our counterparty to the new
confidential identities; in future this will be extended to handle swapping identities with multiple parties.
You can see an example of it being used in ``TwoPartyDealFlow.kt``:
.. container:: codeset .. container:: codeset
@ -71,29 +69,35 @@ You can see an example of it being used in ``TwoPartyDealFlow.kt``:
:end-before: DOCEND 2 :end-before: DOCEND 2
:dedent: 8 :dedent: 8
The swap identities flow goes through the following key steps: ``SwapIdentitiesFlow`` goes through the following key steps:
1. Generate a nonce value to form a challenge to the other nodes. 1. Generate a nonce value to form a challenge to the other nodes
2. Send nonce value to all counterparties, and receive their nonce values. 2. Send nonce value to all counterparties, and receive their nonce values
3. Generate a new confidential identity from our well known identity. 3. Generate a new confidential identity from our well-known identity
4. Create a data blob containing the new confidential identity (public key, name and X.509 certificate path), 4. Create a data blob containing the new confidential identity (public key, name and X.509 certificate path),
and the hash of the nonce values. and the hash of the nonce values
5. Sign the resulting data blob with the confidential identity's private key. 5. Sign the resulting data blob with the confidential identity's private key
6. Send the confidential identity and data blob signature to all counterparties, while receiving theirs. 6. Send the confidential identity and data blob signature to all counterparties, while receiving theirs
7. Verify the signatures to ensure that identities were generated by the involved set of parties. 7. Verify the signatures to ensure that identities were generated by the involved set of parties
8. Verify the confidential identities are owned by the expected well known identities. 8. Verify the confidential identities are owned by the expected well known identities
9. Store the confidential identities and return them to the calling flow. 9. Store the confidential identities and return them to the calling flow
This ensures not only that the confidential identity X.509 certificates are signed by the correct well known identities, This ensures not only that the confidential identity X.509 certificates are signed by the correct well-known
but also that the confidential identity private key is held by the counterparty, and that a party cannot claim ownership identities, but also that the confidential identity private key is held by the counterparty, and that a party cannot
another party's confidential identities belong to its well known identity. claim ownership of another party's confidential identities.
Identity synchronization flow IdentitySyncFlow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
When constructing a transaction whose input states reference confidential identities, it is common for counterparties
to require knowledge of which well-known identity each confidential identity maps to. ``IdentitySyncFlow`` handles this
process. You can see an example of its use in ``TwoPartyTradeFlow.kt``.
When constructing a transaction whose input states reference confidential identities, it is common for other signing ``IdentitySyncFlow`` is divided into two parts:
entities (counterparties) to require to know which well known identities those confidential identities map to. The
``IdentitySyncFlow`` handles this process, and you can see an example of its use in ``TwoPartyTradeFlow.kt``: * ``IdentitySyncFlow.Send``
* ``IdentitySyncFlow.Receive``
``IdentitySyncFlow.Send`` is invoked by the party initiating the identity synchronization:
.. container:: codeset .. container:: codeset
@ -105,20 +109,33 @@ entities (counterparties) to require to know which well known identities those c
The identity synchronization flow goes through the following key steps: The identity synchronization flow goes through the following key steps:
1. Extract participant identities from all input and output states and remove any well known identities. Required signers 1. Extract participant identities from all input and output states and remove any well known identities. Required
on commands are currently ignored as they are presumed to be included in the participants on states, or to be well signers on commands are currently ignored as they are presumed to be included in the participants on states, or to
known identities of services (such as an oracle service). be well-known identities of services (such as an oracle service)
2. For each counterparty node, send a list of the public keys of the confidential identities, and receive back a list 2. For each counterparty node, send a list of the public keys of the confidential identities, and receive back a list
of those the counterparty needs the certificate path for. of those the counterparty needs the certificate path for
3. Verify the requested list of identities contains only confidential identities in the offered list, and abort otherwise. 3. Verify the requested list of identities contains only confidential identities in the offered list, and abort
4. Send the requested confidential identities as ``PartyAndCertificate`` instances to the counterparty. otherwise
4. Send the requested confidential identities as ``PartyAndCertificate`` instances to the counterparty
.. note:: ``IdentitySyncFlow`` works on a push basis. The initiating node can only send confidential identities it has .. note:: ``IdentitySyncFlow`` works on a push basis. The initiating node can only send confidential identities it has
the X.509 certificates for, and the remote nodes can only request confidential identities being offered (are the X.509 certificates for, and the remote nodes can only request confidential identities being offered (are
referenced in the transaction passed to the initiating flow). There is no standard flow for nodes to collect referenced in the transaction passed to the initiating flow). There is no standard flow for nodes to collect
confidential identities before assembling a transaction, and this is left for individual flows to manage if required. confidential identities before assembling a transaction, and this is left for individual flows to manage if
required.
``IdentitySyncFlow`` will serve all confidential identities in the provided transaction, irrespective of well known Meanwhile, ``IdentitySyncFlow.Receive`` is invoked by all the other (non-initiating) parties involved in the identity
synchronization process:
.. container:: codeset
.. literalinclude:: ../../finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt
:language: kotlin
:start-after: DOCSTART 07
:end-before: DOCEND 07
:dedent: 12
``IdentitySyncFlow`` will serve all confidential identities in the provided transaction, irrespective of well-known
identity. This is important for more complex transaction cases with 3+ parties, for example: identity. This is important for more complex transaction cases with 3+ parties, for example:
* Alice is building the transaction, and provides some input state *x* owned by a confidential identity of Alice * Alice is building the transaction, and provides some input state *x* owned by a confidential identity of Alice
@ -126,6 +143,6 @@ identity. This is important for more complex transaction cases with 3+ parties,
* Charlie provides some input state *z* owned by a confidential identity of Charlie * Charlie provides some input state *z* owned by a confidential identity of Charlie
Alice may know all of the confidential identities ahead of time, but Bob not know about Charlie's and vice-versa. Alice may know all of the confidential identities ahead of time, but Bob not know about Charlie's and vice-versa.
The assembled transaction therefore has three input states *x*, *y* and *z*, for which only Alice possesses certificates The assembled transaction therefore has three input states *x*, *y* and *z*, for which only Alice possesses
for all confidential identities. ``IdentitySyncFlow`` must send not just Alice's confidential identity but also any other certificates for all confidential identities. ``IdentitySyncFlow`` must send not just Alice's confidential identity but
identities in the transaction to the Bob and Charlie. also any other identities in the transaction to the Bob and Charlie.

View File

@ -87,9 +87,11 @@ object TwoPartyTradeFlow {
// Verify and sign the transaction. // Verify and sign the transaction.
progressTracker.currentStep = VERIFYING_AND_SIGNING progressTracker.currentStep = VERIFYING_AND_SIGNING
// DOCSTART 07
// Sync identities to ensure we know all of the identities involved in the transaction we're about to // Sync identities to ensure we know all of the identities involved in the transaction we're about to
// be asked to sign // be asked to sign
subFlow(IdentitySyncFlow.Receive(otherSideSession)) subFlow(IdentitySyncFlow.Receive(otherSideSession))
// DOCEND 07
// DOCSTART 5 // DOCSTART 5
val signTransactionFlow = object : SignTransactionFlow(otherSideSession, VERIFYING_AND_SIGNING.childProgressTracker()) { val signTransactionFlow = object : SignTransactionFlow(otherSideSession, VERIFYING_AND_SIGNING.childProgressTracker()) {