Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identity v2 #5598

Merged
merged 5 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 0 additions & 11 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,3 @@ updates:
labels:
- "Type: Dependencies"
- "Implementation: Elixir"

# Maintain dependencies for elixir ockam_vault_software application
- package-ecosystem: "mix"
directory: "/implementations/elixir/ockam/ockam_vault_software"
commit-message:
prefix: "build:"
schedule:
interval: "daily"
labels:
- "Type: Dependencies"
- "Implementation: Elixir"
6 changes: 3 additions & 3 deletions .github/workflows/elixir-ignored.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- ockam_metrics
- ockam_services
- ockam_typed_cbor
- ockam_vault_software
- ockly
steps:
- run: 'echo "Elixir - lint_${{ matrix.mix_project }} - Ignored"'

Expand All @@ -52,7 +52,7 @@ jobs:
- ockam_metrics
- ockam_services
- ockam_typed_cbor
- ockam_vault_software
- ockly
steps:
- run: 'echo "Elixir - build_${{ matrix.mix_project }} - Ignored"'

Expand All @@ -70,6 +70,6 @@ jobs:
- ockam_metrics
- ockam_services
- ockam_typed_cbor
- ockam_vault_software
- ockly
steps:
- run: 'echo "Elixir - test_${{ matrix.mix_project }} - Ignored"'
6 changes: 3 additions & 3 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
- ockam_metrics
- ockam_services
- ockam_typed_cbor
- ockam_vault_software
- ockly
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
with:
Expand All @@ -92,7 +92,7 @@ jobs:
- ockam_metrics
- ockam_services
- ockam_typed_cbor
- ockam_vault_software
- ockly
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
with:
Expand All @@ -117,7 +117,7 @@ jobs:
- ockam_metrics
- ockam_services
- ockam_typed_cbor
- ockam_vault_software
- ockly
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
with:
Expand Down
44 changes: 31 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ members = [
"implementations/rust/ockam/ockam_command",
"implementations/rust/ockam/ockam_core",
"implementations/rust/ockam/ockam_executor",
"implementations/rust/ockam/ockam_ffi",
"implementations/rust/ockam/ockam_identity",
"implementations/rust/ockam/ockam_macros",
"implementations/rust/ockam/ockam_multiaddr",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
use ockam::identity::{AuthorityService, CredentialsIssuerClient, SecureChannelOptions, TrustContext};
use ockam::TcpTransportExtension;
use ockam::{node, route, Context, Result, TcpConnectionOptions};
use ockam::identity::{AuthorityService, CredentialsIssuerClient, SecureChannelOptions, TrustContext, Vault};
use ockam::vault::{Secret, SecretAttributes, SoftwareSigningVault};
use ockam::{route, Context, Result, TcpConnectionOptions};
use ockam::{Node, TcpTransportExtension};

#[ockam::node]
async fn main(ctx: Context) -> Result<()> {
// Create a node with default implementations
let mut node = node(ctx);
let identity_vault = SoftwareSigningVault::create();
// Import the signing secret key to the Vault
let secret = identity_vault
.import_key(
Secret::new(hex::decode("31FF4E1CD55F17735A633FBAB4B838CF88D1252D164735CB3185A6E315438C2C").unwrap()),
SecretAttributes::Ed25519,
)
.await?;

// Create a default Vault but use the signing vault with our secret in it
let mut vault = Vault::create();
vault.identity_vault = identity_vault;

let mut node = Node::builder().with_vault(vault).build(ctx).await?;
// Initialize the TCP Transport
let tcp = node.create_tcp_transport().await?;

// Create an Identity representing the client
// We preload the client vault with a change history and secret key corresponding to the identity identifier
// Pe92f183eb4c324804ef4d62962dea94cf095a265d4d28500c34e1a4e0d5ef638
// I6342c580429b9a0733880bea4fa18f8055871130
// which is an identifier known to the credential issuer, with some preset attributes
//
// We're hard coding this specific identity because its public identifier is known
// to the credential issuer as a member of the production cluster.
let change_history = "01dcf392551f796ef1bcb368177e53f9a5875a962f67279259207d24a01e690721000547c93239ba3d818ec26c9cdadd2a35cbdf1fa3b6d1a731e06164b1079fb7b8084f434b414d5f524b03012000000020a0d205f09cab9a9467591fcee560429aab1215d8136e5c985a6b7dc729e6f08203010140b098463a727454c0e5292390d8f4cbd4dd0cae5db95606832f3d0a138936487e1da1489c40d8a0995fce71cc1948c6bcfd67186467cdd78eab7e95c080141505";
let secret = "41b6873b20d95567bf958e6bab2808e9157720040882630b1bb37a72f4015cd2";
let client = node.import_private_identity(change_history, secret).await?;
let change_history = hex::decode("81a201583ba20101025835a4028201815820530d1c2e9822433b679a66a60b9c2ed47c370cd0ce51cbe1a7ad847b5835a96303f4041a64dd4060051a77a94360028201815840042fff8f6c80603fb1cec4a3cf1ff169ee36889d3ed76184fe1dfbd4b692b02892df9525c61c2f1286b829586d13d5abf7d18973141f734d71c1840520d40a0e").unwrap();
let client = node.import_private_identity(&change_history, &secret).await?;
println!("issuer identifier {}", client.identifier());

// Connect with the credential issuer and authenticate using the latest private
// key of this program's hardcoded identity.
Expand All @@ -28,32 +42,31 @@ async fn main(ctx: Context) -> Result<()> {
let issuer_connection = tcp.connect("127.0.0.1:5000", TcpConnectionOptions::new()).await?;
let issuer_channel = node
.create_secure_channel(
&client.identifier(),
client.identifier(),
route![issuer_connection, "secure"],
SecureChannelOptions::new(),
)
.await?;

let issuer_client = CredentialsIssuerClient::new(route![issuer_channel, "issuer"], node.context()).await?;
let credential = issuer_client.credential().await?;
println!("Credential:\n{credential}");

// Verify that the received credential has indeed be signed by the issuer.
// The issuer identity must be provided out-of-band from a trusted source
// and match the identity used to start the issuer node
let issuer_identity = "0180370b91c5d0aa4af34580a9ab4b8fb2a28351bed061525c96b4f07e75c0ee18000547c93239ba3d818ec26c9cdadd2a35cbdf1fa3b6d1a731e06164b1079fb7b8084f434b414d5f524b03012000000020236f79490d3f683e0c3bf458a7381c366c99a8f2b2ac406db1ef8c130111f12703010140b23fddceb11cea25602aa681b6ef6abda036722c27a6dee291f1d6b2234a127af21cc79de2252201f27e7e34e0bf5064adbf3d01eb355aff4bf5c90b8f1fd80a";
let issuer_identity = "81a201583ba20101025835a4028201815820afbca9cf5d440147450f9f0d0a038a337b3fe5c17086163f2c54509558b62ef403f4041a64dd404a051a77a9434a0282018158407754214545cda6e7ff49136f67c9c7973ec309ca4087360a9f844aac961f8afe3f579a72c0c9530f3ff210f02b7c5f56e96ce12ee256b01d7628519800723805";
let issuer = node.import_identity_hex(issuer_identity).await?;
node.credentials()
.verify_credential(&client.identifier(), &[issuer.clone()], credential.clone())
.credentials_verification()
.verify_credential(Some(client.identifier()), &[issuer.identifier().clone()], &credential)
.await?;

// Create a trust context that will be used to authenticate credential exchanges
let trust_context = TrustContext::new(
"trust_context_id".to_string(),
Some(AuthorityService::new(
node.identities().identities_reader(),
node.credentials(),
issuer.identifier(),
issuer.identifier().clone(),
None,
)),
);
Expand All @@ -62,7 +75,7 @@ async fn main(ctx: Context) -> Result<()> {
let server_connection = tcp.connect("127.0.0.1:4000", TcpConnectionOptions::new()).await?;
let channel = node
.create_secure_channel(
&client.identifier(),
client.identifier(),
route![server_connection, "secure"],
SecureChannelOptions::new()
.with_trust_context(trust_context)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
use ockam::access_control::AllowAll;
use ockam::access_control::IdentityIdAccessControl;
use ockam::identity::CredentialsIssuer;
use ockam::identity::SecureChannelListenerOptions;
use ockam::TcpTransportExtension;
use ockam::{node, Context, Result, TcpListenerOptions};
use ockam::identity::{CredentialsIssuer, SecureChannelListenerOptions, Vault};
use ockam::vault::{Secret, SecretAttributes, SoftwareSigningVault};
use ockam::{Context, Result, TcpListenerOptions};
use ockam::{Node, TcpTransportExtension};

#[ockam::node]
async fn main(ctx: Context) -> Result<()> {
// Create a node with default implementations
let node = node(ctx);
let identity_vault = SoftwareSigningVault::create();
// Import the signing secret key to the Vault
let secret = identity_vault
.import_key(
Secret::new(hex::decode("0127359911708ef4de9adaaf27c357501473c4a10a5326a69c1f7f874a0cd82e").unwrap()),
SecretAttributes::Ed25519,
)
.await?;

// Create a default Vault but use the signing vault with our secret in it
let mut vault = Vault::create();
vault.identity_vault = identity_vault;

let node = Node::builder().with_vault(vault).build(ctx).await?;

let issuer_identity = "0180370b91c5d0aa4af34580a9ab4b8fb2a28351bed061525c96b4f07e75c0ee18000547c93239ba3d818ec26c9cdadd2a35cbdf1fa3b6d1a731e06164b1079fb7b8084f434b414d5f524b03012000000020236f79490d3f683e0c3bf458a7381c366c99a8f2b2ac406db1ef8c130111f12703010140b23fddceb11cea25602aa681b6ef6abda036722c27a6dee291f1d6b2234a127af21cc79de2252201f27e7e34e0bf5064adbf3d01eb355aff4bf5c90b8f1fd80a";
let secret = "9278735d525efceef16bfd9143d3534759f3d388e460e6002134b9541e06489f";
let issuer = node.import_private_identity(issuer_identity, secret).await?;
let issuer_identity = hex::decode("81a201583ba20101025835a4028201815820afbca9cf5d440147450f9f0d0a038a337b3fe5c17086163f2c54509558b62ef403f4041a64dd404a051a77a9434a0282018158407754214545cda6e7ff49136f67c9c7973ec309ca4087360a9f844aac961f8afe3f579a72c0c9530f3ff210f02b7c5f56e96ce12ee256b01d7628519800723805").unwrap();
let issuer = node.import_private_identity(&issuer_identity, &secret).await?;
println!("issuer identifier {}", issuer.identifier());

// Tell the credential issuer about a set of public identifiers that are
// known, in advance, to be members of the production cluster.
let known_identifiers = vec![
"Pe92f183eb4c324804ef4d62962dea94cf095a265d4d28500c34e1a4e0d5ef638".try_into()?,
"Pada09e0f96e56580f6a0cb54f55ecbde6c973db6732e30dfb39b178760aed041".try_into()?,
"I6342c580429b9a0733880bea4fa18f8055871130".try_into()?, // Client Identifier
"I2c3b0ef15c12fe43d405497fcfc46318da46d0f5".try_into()?, // Server Identifier
];

// Tell this credential issuer about the attributes to include in credentials
Expand All @@ -32,12 +43,17 @@ async fn main(ctx: Context) -> Result<()> {
//
// For a different application this attested attribute set can be different and
// distinct for each identifier, but for this example we'll keep things simple.
let credential_issuer =
CredentialsIssuer::new(node.identities(), issuer.identifier(), "trust_context".into()).await?;
let credential_issuer = CredentialsIssuer::new(
node.identities().repository(),
node.credentials(),
issuer.identifier(),
"trust_context".into(),
)
.await?;
for identifier in known_identifiers.iter() {
node.identities()
.repository()
.put_attribute_value(identifier, "cluster", "production")
.put_attribute_value(identifier, b"cluster".to_vec(), b"production".to_vec())
.await?;
}

Expand All @@ -49,7 +65,7 @@ async fn main(ctx: Context) -> Result<()> {
// Start a secure channel listener that only allows channels where the identity
// at the other end of the channel can authenticate with the latest private key
// corresponding to one of the above known public identifiers.
node.create_secure_channel_listener(&issuer.identifier(), "secure", sc_listener_options)
node.create_secure_channel_listener(issuer.identifier(), "secure", sc_listener_options)
.await?;

// Start a credential issuer worker that will only accept incoming requests from
Expand Down
Loading
Loading