mirror of
https://github.com/corda/corda.git
synced 2025-04-06 19:07:08 +00:00
Adds receiver side of sync flow to ID docs. Cleanup.
This commit is contained in:
parent
5cd6f61a7f
commit
3a69f2a60c
@ -7,61 +7,59 @@ API: Identity
|
||||
|
||||
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``
|
||||
* ``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
|
||||
of the transaction's validity, but equally important that you don't learn anything about who was involved in that
|
||||
transaction. In these cases ``AnonymousParty`` should be used by flows constructing when transaction states and commands.
|
||||
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).
|
||||
The identity service allows flows to resolve ``AnonymousParty`` to ``Party``, but only if the anonymous party's
|
||||
identity has already been registered with the node (typically 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
|
||||
well as ensuring a consistent rendering of the names in plain text.
|
||||
Party names use the ``CordaX500Name`` data class, which enforces the structure of names within Corda, as well as
|
||||
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
|
||||
information. For example, it is possible to construct a Transaction using an AnonymousParty, so nobody can learn of your
|
||||
involvement by inspection of the transaction, yet prove to specific counterparts that this AnonymousParty actually is
|
||||
owned by your well known identity. This disclosure is achieved through the use of the PartyAndCertificate data class
|
||||
which can be propagated to those who need to know, and contains the Party's X.509 certificate path to provide proof of
|
||||
ownership by a well known identity.
|
||||
Support for both ``Party`` and ``AnonymousParty`` classes in Corda enables sophisticated selective disclosure of
|
||||
identity information. For example, it is possible to construct a transaction using an ``AnonymousParty`` (so nobody can
|
||||
learn of your involvement by inspection of the transaction), yet prove to specific counterparts that this
|
||||
``AnonymousParty`` actually corresponds to your well-known identity. This is achieved using the
|
||||
``PartyAndCertificate`` data class, which contains the X.509 certificate path proving that a given ``AnonymousParty``
|
||||
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
|
||||
scenario the certificate path proves its issuance by the Doorman service.
|
||||
The ``PartyAndCertificate`` class is also used by the network map service to represent well-known identities, with the
|
||||
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 parties who
|
||||
are not involved in the transaction cannot identify its participants. They are owned by a well known identity, which
|
||||
must sign the X.509 certificate. Before constructing a new transaction the involved parties must generate and send new
|
||||
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 transaction.
|
||||
Confidential identities are key pairs where the corresponding X.509 certificate (and path) are not made public, so that
|
||||
parties who are not involved in the transaction cannot identify the owner. They are owned by a well-known identity,
|
||||
which must sign the X.509 certificate. Before constructing a new transaction the involved parties must generate and
|
||||
exchange new confidential identities, 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
|
||||
transaction.
|
||||
|
||||
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
|
||||
from both parties. ``CollectSignaturesFlow`` requires that a confidential identity of the initiating node has signed
|
||||
the transaction, and verifying this requires the receiving node has a copy of the confidential identity for the input
|
||||
state. ``IdentitySyncFlow`` can be used to synchronize the confidential identities we have the certificate paths for, in
|
||||
a single transaction, to another node.
|
||||
parties are. One example is the ``TwoPartyTradeFlow``, where an existing asset is exchanged for cash. If confidential
|
||||
identities are being used, the buyer will want to ensure that the asset being transferred is owned by the seller, and
|
||||
the seller will likewise want to ensure that the cash being transferred is owned by the buyer. Verifying this requires
|
||||
both nodes to have a copy of the confidential identities for the asset and cash input states. ``IdentitySyncFlow``
|
||||
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
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
``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
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``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``:
|
||||
You can see an example of using ``SwapIdentitiesFlow`` in ``TwoPartyDealFlow.kt``:
|
||||
|
||||
.. container:: codeset
|
||||
|
||||
@ -71,29 +69,35 @@ You can see an example of it being used in ``TwoPartyDealFlow.kt``:
|
||||
:end-before: DOCEND 2
|
||||
: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.
|
||||
2. Send nonce value to all counterparties, and receive their nonce values.
|
||||
3. Generate a new confidential identity from our well known identity.
|
||||
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
|
||||
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),
|
||||
and the hash of the nonce values.
|
||||
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.
|
||||
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.
|
||||
9. Store the confidential identities and return them to the calling flow.
|
||||
and the hash of the nonce values
|
||||
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
|
||||
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
|
||||
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,
|
||||
but also that the confidential identity private key is held by the counterparty, and that a party cannot claim ownership
|
||||
another party's confidential identities belong to its well known identity.
|
||||
This ensures not only that the confidential identity X.509 certificates are signed by the correct well-known
|
||||
identities, but also that the confidential identity private key is held by the counterparty, and that a party cannot
|
||||
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
|
||||
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`` is divided into two parts:
|
||||
|
||||
* ``IdentitySyncFlow.Send``
|
||||
* ``IdentitySyncFlow.Receive``
|
||||
|
||||
``IdentitySyncFlow.Send`` is invoked by the party initiating the identity synchronization:
|
||||
|
||||
.. 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:
|
||||
|
||||
1. Extract participant identities from all input and output states and remove any well known identities. Required signers
|
||||
on commands are currently ignored as they are presumed to be included in the participants on states, or to be well
|
||||
known identities of services (such as an oracle service).
|
||||
1. Extract participant identities from all input and output states and remove any well known identities. Required
|
||||
signers on commands are currently ignored as they are presumed to be included in the participants on states, or to
|
||||
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
|
||||
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.
|
||||
4. Send the requested confidential identities as ``PartyAndCertificate`` instances to the counterparty.
|
||||
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
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
* 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
|
||||
|
||||
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
|
||||
for all confidential identities. ``IdentitySyncFlow`` must send not just Alice's confidential identity but also any other
|
||||
identities in the transaction to the Bob and Charlie.
|
||||
The assembled transaction therefore has three input states *x*, *y* and *z*, for which only Alice possesses
|
||||
certificates for all confidential identities. ``IdentitySyncFlow`` must send not just Alice's confidential identity but
|
||||
also any other identities in the transaction to the Bob and Charlie.
|
@ -87,9 +87,11 @@ object TwoPartyTradeFlow {
|
||||
// Verify and sign the transaction.
|
||||
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
|
||||
// be asked to sign
|
||||
subFlow(IdentitySyncFlow.Receive(otherSideSession))
|
||||
// DOCEND 07
|
||||
|
||||
// DOCSTART 5
|
||||
val signTransactionFlow = object : SignTransactionFlow(otherSideSession, VERIFYING_AND_SIGNING.childProgressTracker()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user