/// <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;
        }
Exemple #2
0
        /// <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)
            });
        }