mirror of
https://github.com/corda/corda.git
synced 2025-04-07 11:27:01 +00:00
CORDA-1173 - api-identity and docs (#2743)
This commit is contained in:
parent
6cebd3b9a8
commit
42208a5aae
@ -12,14 +12,14 @@ import net.corda.core.utilities.unwrap
|
||||
|
||||
object IdentitySyncFlow {
|
||||
/**
|
||||
* Flow for ensuring that our counterparties in a transaction have the full certificate paths for *our* confidential
|
||||
* identities used in states present in the transaction. This is intended for use as a subflow of another flow, typically between
|
||||
* transaction assembly and signing. An example of where this is useful is where a recipient of a [Cash] state wants
|
||||
* to know that it is being paid by the correct party, and the owner of the state is a confidential identity of that
|
||||
* party. This flow would send a copy of the confidential identity path to the recipient, enabling them to verify that
|
||||
* identity.
|
||||
* Flow for ensuring that our counter-parties in a transaction have the full certificate paths for *our*
|
||||
* confidential identities used in states present in the transaction. This is intended for use as a sub-flow of
|
||||
* another flow, typically between transaction assembly and signing. An example of where this is useful is where
|
||||
* 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
|
||||
* confidential identity of that party. This flow would send a copy of the confidential identity path to the
|
||||
* 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>,
|
||||
val tx: WireTransaction,
|
||||
override val progressTracker: ProgressTracker) : FlowLogic<Unit>() {
|
||||
@ -81,7 +81,7 @@ object IdentitySyncFlow {
|
||||
override val progressTracker: ProgressTracker = ProgressTracker(RECEIVING_IDENTITIES, RECEIVING_CERTIFICATES)
|
||||
|
||||
@Suspendable
|
||||
override fun call(): Unit {
|
||||
override fun call() {
|
||||
progressTracker.currentStep = RECEIVING_IDENTITIES
|
||||
val allIdentities = otherSideSession.receive<List<AbstractParty>>().unwrap { it }
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
@StartableByRPC
|
||||
@ -38,7 +38,7 @@ class SwapIdentitiesFlow(private val otherParty: Party,
|
||||
|
||||
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,
|
||||
* 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.
|
||||
@ -90,8 +90,8 @@ class SwapIdentitiesFlow(private val otherParty: Party,
|
||||
val confidentialIdentity: PartyAndCertificate = confidentialIdentityBytes.bytes.deserialize()
|
||||
validateAndRegisterIdentity(serviceHub.identityService, otherParty, confidentialIdentity, theirSigBytes)
|
||||
}
|
||||
identities.put(ourIdentity, legalIdentityAnonymous.party.anonymise())
|
||||
identities.put(otherParty, anonymousOtherSide.party.anonymise())
|
||||
identities[ourIdentity] = legalIdentityAnonymous.party.anonymise()
|
||||
identities[otherParty] = anonymousOtherSide.party.anonymise()
|
||||
}
|
||||
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
|
||||
* to represent the named entity. This is pairs 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'
|
||||
* 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 paired with an X.509 certificate (which asserts the signing identity says
|
||||
* the key represents the named entity) and protects against a malicious party incorrectly claiming others'
|
||||
* keys.
|
||||
*/
|
||||
@CordaSerializable
|
||||
|
@ -54,7 +54,7 @@ counterparty.
|
||||
|
||||
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
|
||||
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.
|
||||
@ -71,16 +71,13 @@ You can see an example of using ``SwapIdentitiesFlow`` in ``TwoPartyDealFlow.kt`
|
||||
|
||||
``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
|
||||
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
|
||||
1. Generate a new confidential identity from our well-known identity
|
||||
2. Create a ``CertificateOwnershipAssertion`` object containing the new confidential identity (X500 name, public key)
|
||||
3. Sign this object with the confidential identity's private key
|
||||
4. Send the confidential identity and aforementioned signature to counterparties, while receiving theirs
|
||||
5. Verify the signatures to ensure that identities were generated by the involved set of parties
|
||||
6. Verify the confidential identities are owned by the expected well known identities
|
||||
7. 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user