mirror of
https://github.com/corda/corda.git
synced 2025-06-11 20:01:46 +00:00
CORDA-1173 - api-identity and docs (#2743)
This commit is contained in:
committed by
Katelyn Baker
parent
6cebd3b9a8
commit
42208a5aae
@ -12,14 +12,14 @@ import net.corda.core.utilities.unwrap
|
|||||||
|
|
||||||
object IdentitySyncFlow {
|
object IdentitySyncFlow {
|
||||||
/**
|
/**
|
||||||
* Flow for ensuring that our counterparties in a transaction have the full certificate paths for *our* confidential
|
* Flow for ensuring that our counter-parties in a transaction have the full certificate paths for *our*
|
||||||
* identities used in states present in the transaction. This is intended for use as a subflow of another flow, typically between
|
* confidential identities used in states present in the transaction. This is intended for use as a sub-flow of
|
||||||
* transaction assembly and signing. An example of where this is useful is where a recipient of a [Cash] state wants
|
* another flow, typically between transaction assembly and signing. An example of where this is useful is where
|
||||||
* to know that it is being paid by the correct party, and the owner of the state is a confidential identity of that
|
* a recipient of a state wants to know that it is being paid by the correct party, and the owner of the state is a
|
||||||
* party. This flow would send a copy of the confidential identity path to the recipient, enabling them to verify that
|
* confidential identity of that party. This flow would send a copy of the confidential identity path to the
|
||||||
* identity.
|
* recipient, enabling them to verify that identity.
|
||||||
*/
|
*/
|
||||||
// TODO: Can this be triggered automatically from [SendTransactionFlow]
|
// TODO: Can this be triggered automatically from [SendTransactionFlow]?
|
||||||
class Send(val otherSideSessions: Set<FlowSession>,
|
class Send(val otherSideSessions: Set<FlowSession>,
|
||||||
val tx: WireTransaction,
|
val tx: WireTransaction,
|
||||||
override val progressTracker: ProgressTracker) : FlowLogic<Unit>() {
|
override val progressTracker: ProgressTracker) : FlowLogic<Unit>() {
|
||||||
@ -81,7 +81,7 @@ object IdentitySyncFlow {
|
|||||||
override val progressTracker: ProgressTracker = ProgressTracker(RECEIVING_IDENTITIES, RECEIVING_CERTIFICATES)
|
override val progressTracker: ProgressTracker = ProgressTracker(RECEIVING_IDENTITIES, RECEIVING_CERTIFICATES)
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): Unit {
|
override fun call() {
|
||||||
progressTracker.currentStep = RECEIVING_IDENTITIES
|
progressTracker.currentStep = RECEIVING_IDENTITIES
|
||||||
val allIdentities = otherSideSession.receive<List<AbstractParty>>().unwrap { it }
|
val allIdentities = otherSideSession.receive<List<AbstractParty>>().unwrap { it }
|
||||||
val unknownIdentities = allIdentities.filter { serviceHub.identityService.wellKnownPartyFromAnonymous(it) == null }
|
val unknownIdentities = allIdentities.filter { serviceHub.identityService.wellKnownPartyFromAnonymous(it) == null }
|
||||||
|
@ -23,7 +23,7 @@ import java.util.*
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Very basic flow which generates new confidential identities for parties in a transaction and exchanges the transaction
|
* Very basic flow which generates new confidential identities for parties in a transaction and exchanges the transaction
|
||||||
* key and certificate paths between the parties. This is intended for use as a subflow of another flow which builds a
|
* key and certificate paths between the parties. This is intended for use as a sub-flow of another flow which builds a
|
||||||
* transaction.
|
* transaction.
|
||||||
*/
|
*/
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
@ -38,7 +38,7 @@ class SwapIdentitiesFlow(private val otherParty: Party,
|
|||||||
|
|
||||||
fun tracker() = ProgressTracker(AWAITING_KEY)
|
fun tracker() = ProgressTracker(AWAITING_KEY)
|
||||||
/**
|
/**
|
||||||
* Generate the determinstic data blob the confidential identity's key holder signs to indicate they want to
|
* Generate the deterministic data blob the confidential identity's key holder signs to indicate they want to
|
||||||
* represent the subject named in the X.509 certificate. Note that this is never actually sent between nodes,
|
* represent the subject named in the X.509 certificate. Note that this is never actually sent between nodes,
|
||||||
* but only the signature is sent. The blob is built independently on each node and the received signature
|
* but only the signature is sent. The blob is built independently on each node and the received signature
|
||||||
* verified against the expected blob, rather than exchanging the blob.
|
* verified against the expected blob, rather than exchanging the blob.
|
||||||
@ -90,8 +90,8 @@ class SwapIdentitiesFlow(private val otherParty: Party,
|
|||||||
val confidentialIdentity: PartyAndCertificate = confidentialIdentityBytes.bytes.deserialize()
|
val confidentialIdentity: PartyAndCertificate = confidentialIdentityBytes.bytes.deserialize()
|
||||||
validateAndRegisterIdentity(serviceHub.identityService, otherParty, confidentialIdentity, theirSigBytes)
|
validateAndRegisterIdentity(serviceHub.identityService, otherParty, confidentialIdentity, theirSigBytes)
|
||||||
}
|
}
|
||||||
identities.put(ourIdentity, legalIdentityAnonymous.party.anonymise())
|
identities[ourIdentity] = legalIdentityAnonymous.party.anonymise()
|
||||||
identities.put(otherParty, anonymousOtherSide.party.anonymise())
|
identities[otherParty] = anonymousOtherSide.party.anonymise()
|
||||||
}
|
}
|
||||||
return identities
|
return identities
|
||||||
}
|
}
|
||||||
@ -101,9 +101,9 @@ class SwapIdentitiesFlow(private val otherParty: Party,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class used only in the context of asserting the owner of the private key for the listed key wants to use it
|
* Data class used only in the context of asserting that the owner of the private key for the listed key wants to use it
|
||||||
* to represent the named entity. This is pairs with an X.509 certificate (which asserts the signing identity says
|
* to represent the named entity. This is paired with an X.509 certificate (which asserts the signing identity says
|
||||||
* the key represents the named entity), but protects against a certificate authority incorrectly claiming others'
|
* the key represents the named entity) and protects against a malicious party incorrectly claiming others'
|
||||||
* keys.
|
* keys.
|
||||||
*/
|
*/
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
|
@ -54,7 +54,7 @@ counterparty.
|
|||||||
|
|
||||||
SwapIdentitiesFlow
|
SwapIdentitiesFlow
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
``SwapIdentitiesFlow`` is typically run as a subflow of another flow. It takes as its sole constructor argument the
|
``SwapIdentitiesFlow`` is typically run as a sub-flow 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
|
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
|
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.
|
identities with multiple parties at once.
|
||||||
@ -71,16 +71,13 @@ You can see an example of using ``SwapIdentitiesFlow`` in ``TwoPartyDealFlow.kt`
|
|||||||
|
|
||||||
``SwapIdentitiesFlow`` 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 new confidential identity from our well-known identity
|
||||||
2. Send nonce value to all counterparties, and receive their nonce values
|
2. Create a ``CertificateOwnershipAssertion`` object containing the new confidential identity (X500 name, public key)
|
||||||
3. Generate a new confidential identity from our well-known identity
|
3. Sign this object with the confidential identity's private key
|
||||||
4. Create a data blob containing the new confidential identity (public key, name and X.509 certificate path),
|
4. Send the confidential identity and aforementioned signature to counterparties, while receiving theirs
|
||||||
and the hash of the nonce values
|
5. Verify the signatures to ensure that identities were generated by the involved set of parties
|
||||||
5. Sign the resulting data blob with the confidential identity's private key
|
6. Verify the confidential identities are owned by the expected well known identities
|
||||||
6. Send the confidential identity and data blob signature to all counterparties, while receiving theirs
|
7. Store the confidential identities and return them to the calling flow
|
||||||
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
|
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
|
identities, but also that the confidential identity private key is held by the counterparty, and that a party cannot
|
||||||
|
Reference in New Issue
Block a user