/// <summary> Initializes a new instance of ConfidentialLedgerClient. </summary> /// <param name="ledgerUri"> The Confidential Ledger URL, for example https://contoso.confidentialledger.azure.com. </param> /// <param name="credential"> A credential used to authenticate to an Azure Service. </param> /// <param name="options"> The options for configuring the client. </param> public ConfidentialLedgerClient(Uri ledgerUri, TokenCredential credential, ConfidentialLedgerClientOptions options = null) { if (ledgerUri == null) { throw new ArgumentNullException(nameof(ledgerUri)); } if (credential == null) { throw new ArgumentNullException(nameof(credential)); } var actualOptions = options ?? new ConfidentialLedgerClientOptions(); var transportOptions = GetIdentityServerTlsCertAndTrust(ledgerUri, actualOptions); ClientDiagnostics = new ClientDiagnostics(actualOptions, true); _tokenCredential = credential; var authPolicy = new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes); _pipeline = HttpPipelineBuilder.Build( actualOptions, Array.Empty <HttpPipelinePolicy>(), new HttpPipelinePolicy[] { authPolicy }, transportOptions, new ResponseClassifier()); _ledgerUri = ledgerUri; _apiVersion = actualOptions.Version; }
/// <summary> Initializes a new instance of ConfidentialLedgerClient. </summary> /// <param name="ledgerUri"> The Confidential Ledger URL, for example https://contoso.confidentialledger.azure.com. </param> /// <param name="credential"> A credential used to authenticate to an Azure Service. </param> /// <param name="options"> The options for configuring the client. </param> public ConfidentialLedgerClient(Uri ledgerUri, TokenCredential credential, ConfidentialLedgerClientOptions options = null) { if (ledgerUri == null) { throw new ArgumentNullException(nameof(ledgerUri)); } if (credential == null) { throw new ArgumentNullException(nameof(credential)); } options ??= new ConfidentialLedgerClientOptions(); _clientDiagnostics = new ClientDiagnostics(options); clientDiagnostics = _clientDiagnostics; _tokenCredential = credential; var authPolicy = new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes); _pipeline = HttpPipelineBuilder.Build( options, new HttpPipelinePolicy[] { new LowLevelCallbackPolicy() }, new HttpPipelinePolicy[] { authPolicy }, new ResponseClassifier()); _ledgerUri = ledgerUri; _apiVersion = options.Version; DefaultPollingInterval = options.OperationPollingInterval; }
/// <summary> Initializes a new instance of ConfidentialLedgerIdentityServiceClient. </summary> /// <param name="identityServiceUri"> The Identity Service URL, for example https://identity.accledger.azure.com. </param> /// <param name="options"> The options for configuring the client. </param> public ConfidentialLedgerIdentityServiceClient(Uri identityServiceUri, ConfidentialLedgerClientOptions options = null) { if (identityServiceUri == null) { throw new ArgumentNullException(nameof(identityServiceUri)); } // TODO: properly generate the client without a credential. _tokenCredential = null; if (_tokenCredential != null) { // Do nothing. } options ??= new ConfidentialLedgerClientOptions(); ClientDiagnostics = new ClientDiagnostics(options); _pipeline = HttpPipelineBuilder.Build(options, Array.Empty <HttpPipelinePolicy>(), Array.Empty <HttpPipelinePolicy>(), new ResponseClassifier()); _identityServiceUri = identityServiceUri; _apiVersion = options.Version; }
internal static HttpPipelineTransportOptions GetIdentityServerTlsCertAndTrust(Uri ledgerUri, ConfidentialLedgerClientOptions options) { var identityClient = new ConfidentialLedgerIdentityServiceClient(new Uri("https://identity.accledger.azure.com"), options); // Get the ledger's TLS certificate for our ledger. var ledgerId = ledgerUri.Host.Substring(0, ledgerUri.Host.IndexOf('.')); Response response = identityClient.GetLedgerIdentity(ledgerId, new()); // extract the ECC PEM value from the response. var eccPem = JsonDocument.Parse(response.Content) .RootElement .GetProperty("ledgerTlsCertificate") .GetString(); // construct an X509Certificate2 with the ECC PEM value. var span = new ReadOnlySpan <char>(eccPem.ToCharArray()); var ledgerTlsCert = PemReader.LoadCertificate(span, null, PemReader.KeyType.Auto, true); X509Chain certificateChain = new(); certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; certificateChain.ChainPolicy.VerificationTime = DateTime.Now; certificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0); certificateChain.ChainPolicy.ExtraStore.Add(ledgerTlsCert); // Define a validation function to ensure that the ledger certificate is trusted by the ledger identity TLS certificate. bool CertValidationCheck(X509Certificate2 cert) { bool isChainValid = certificateChain.Build(cert); if (!isChainValid) { return(false); } var isCertSignedByTheTlsCert = certificateChain.ChainElements.Cast <X509ChainElement>() .Any(x => x.Certificate.Thumbprint == ledgerTlsCert.Thumbprint); return(isCertSignedByTheTlsCert); } return(new HttpPipelineTransportOptions { ServerCertificateCustomValidationCallback = args => CertValidationCheck(args.Certificate) }); }