Files
2026-04-02 16:48:03 +02:00

515 lines
21 KiB
C#

#region Using Statements
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json;
#endregion
namespace ClearstreamAPIConnector
{
class Program
{
// callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
var result = cert.Subject.Contains("YourServerName");
return result;
}
/// <summary>
/// Get our refresh token
/// </summary>
/// <param name="originalToken"></param>
/// <returns></returns>
private static async Task<Token?> GetRefreshTokenAsync(Token originalToken)
{
const string username = "stb2_01014165_1000181";
const string certPw = "clearstream";
#region Private Member
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
#endregion
Token? tok = null;
// First create a proxy object
var proxy = new WebProxy
{
Address = new Uri($"http://l7fwout.usinet.it:3128"),
BypassProxyOnLocal = false,
UseDefaultCredentials = false,
Credentials = CredentialCache.DefaultNetworkCredentials
};
// check certificate chain
ServicePointManager.ServerCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
{
Console.WriteLine("Ssl Policy Errors:");
switch (sslPolicyErrors)
{
case SslPolicyErrors.None:
Console.WriteLine("No error in certificate found");
break;
case SslPolicyErrors.RemoteCertificateNotAvailable:
Console.WriteLine("RemoteCertificateNotAvailable");
break;
case SslPolicyErrors.RemoteCertificateNameMismatch:
Console.WriteLine("RemoteCertificateNameMismatch");
break;
case SslPolicyErrors.RemoteCertificateChainErrors:
Console.WriteLine("RemoteCertificateChainErrors");
break;
}
// call our validation logic
//return ValidateServerCertificate(sender, certificate, chain, sslPolicyErrors);
Console.WriteLine("Overriding cert chain errors. Proceeding...");
return true;
};
// configure endpoint and certificate
try
{
var remoteAddress = $"{clearstreamApiEndpointUrl}authmanager/oauth2/access_token";
var certFile = @"./Cert/P12/xact-api-credentials-3des.p12";
var certificates = new X509Certificate2Collection();
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
// values to pass on to service
var values = new Dictionary<string, string>
{
{ "grant_type", "refresh_token" },{"refresh_token",originalToken.refresh_token},
{ "username", username},
};
// encode it in url form...
var data = new FormUrlEncodedContent(values);
// use modern http client implementation to call endpoint
using var httpHandler = new HttpClientHandler();
httpHandler.ClientCertificates.Add(certificates[0]);
httpHandler.Proxy = proxy;
using var client = new HttpClient(httpHandler);
// handle communiction with API
var response = await client.PostAsync(remoteAddress, data);
// get our response content
var responseContent = await response.Content.ReadAsStringAsync();
// get our token
tok = JsonSerializer.Deserialize<Token>(responseContent);
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}.");
}
return tok;
}
/// <summary>
/// Get Elibility Token
/// </summary>
/// <returns></returns>
private static async Task<Token> GetElibilityTokenAsync()
{
//string scope = "allow ocapi-playground-v1";
var scopeDi = "allow digital-instruments";
var username = "stb2_01014165_1000181";
var password = "Creation1,";
var certPw = "clearstream";
#region Private Member
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
#endregion
Token? tok = null;
// First create a proxy object
//var proxy = new WebProxy
//{
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
// BypassProxyOnLocal = false,
// UseDefaultCredentials = false,
// Credentials = CredentialCache.DefaultNetworkCredentials
//};
// check certificate chain
ServicePointManager.ServerCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
{
Console.WriteLine("Ssl Policy Errors:");
switch (sslPolicyErrors)
{
case SslPolicyErrors.None:
Console.WriteLine("No error in certificate found");
break;
case SslPolicyErrors.RemoteCertificateNotAvailable:
Console.WriteLine("RemoteCertificateNotAvailable");
break;
case SslPolicyErrors.RemoteCertificateNameMismatch:
Console.WriteLine("RemoteCertificateNameMismatch");
break;
case SslPolicyErrors.RemoteCertificateChainErrors:
Console.WriteLine("RemoteCertificateChainErrors");
break;
}
Console.WriteLine("Overriding cert chain errors. Proceeding...");
return true;
};
// configure endpoint and certificate
try
{
var remoteAddress = $"{clearstreamApiEndpointUrl}authmanager/oauth2/access_token";
var certFile = @".\Cert\P12\xact-api-credentials-3des.p12";
X509Certificate2Collection certificates = new();
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
// values to pass on to service
var values = new Dictionary<string, string>
{
{ "grant_type", "password" },
//{ "scope", scope},
{"scope", scopeDi },
{ "username", username},
{ "password", password},
};
// encode it in url form...
var data = new FormUrlEncodedContent(values);
// use modern http client implementation to call endpoint
using var httpHandler = new HttpClientHandler();
httpHandler.ClientCertificates.Add(certificates[0]);
//httpHandler.Proxy = proxy;
using var client = new HttpClient(httpHandler);
// handle communiction with API
var response = await client.PostAsync(remoteAddress, data);
// get our response content
var responseContent = await response.Content.ReadAsStringAsync();
// get our token
tok = JsonSerializer.Deserialize<Token>(responseContent);
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}.");
}
return tok;
}
/// <summary>
/// Get all associcated templates
/// </summary>
/// <param name="accessToken">Bearer token derived from OAuth2.0 request</param>
/// <returns>JSON with all templates available as a <see cref="string"/></returns>
static async Task<DiTemplateList> GetAllTemplates(Token accessToken)
{
Console.WriteLine("Attempting to get all templates for our account");
if (accessToken == null)
{
throw new ArgumentNullException(nameof(accessToken));
}
DiTemplateList templates = null;
var certPw = "clearstream";
#region Private Member
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
#endregion
var remoteAddress = $"{clearstreamApiEndpointUrl}digital-instruments/di/templates";
// First create a proxy object
// var proxy = new WebProxy
// {
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
// BypassProxyOnLocal = false,
// UseDefaultCredentials = false,
// Credentials = CredentialCache.DefaultNetworkCredentials
// };
try
{
var certFile = @"./Cert/P12/xact-api-credentials-3des.p12";
var certificates = new X509Certificate2Collection();
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
// use modern http client implementation to call endpoint
using var httpHandler = new HttpClientHandler();
httpHandler.ClientCertificates.Add(certificates[0]);
// httpHandler.Proxy = proxy;
using var client = new HttpClient(new LoggingHandler(httpHandler));
// handle additional client header
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken.access_token}");
// handle communiction with API
var response = await client.GetAsync(remoteAddress);
// get our response content
var responseContent = await response.Content.ReadAsStringAsync();
templates = JsonSerializer.Deserialize<DiTemplateList>(responseContent);
Console.WriteLine($"Received the following content from {remoteAddress}: '{responseContent}'");
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}.");
}
return templates;
}
/// <summary>
/// Call the playground API asynchronously
/// </summary>
/// <param name="accessToken"></param>
/// <returns></returns>
static async Task<string> CallClearstreamPlaygroundApiAsync(Token accessToken)
{
if (accessToken == null)
{
throw new ArgumentNullException(nameof(accessToken));
}
var jsonContent = string.Empty;
var certPw = "clearstream";
#region Private Member
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
#endregion
var remoteAddress = $"{clearstreamApiEndpointUrl}/playground/v1/echo?value=Hello%20World";
// // First create a proxy object
// var proxy = new WebProxy
// {
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
// BypassProxyOnLocal = false,
// UseDefaultCredentials = false,
// Credentials = CredentialCache.DefaultNetworkCredentials
// };
try
{
var certFile = @"./Cert/P12/xact-api-credentials-3des.p12";
var certificates = new X509Certificate2Collection();
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
// values to pass on to service
var values = new Dictionary<string, string>();
// use modern http client implementation to call endpoint
using var httpHandler = new HttpClientHandler();
httpHandler.ClientCertificates.Add(certificates[0]);
// httpHandler.Proxy = proxy;
using var client = new HttpClient(httpHandler);
// handle additional client header
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken.access_token}");
// handle communiction with API
var response = await client.GetAsync(remoteAddress);
// get our response content
var responseContent = await response.Content.ReadAsStringAsync();
jsonContent = responseContent;
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}.");
}
return jsonContent;
}
/// <summary>
/// Validate the whole certificate chain using the cacert certificate
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine("Checking server certificate...");
if (sslPolicyErrors == SslPolicyErrors.None)
{
Console.WriteLine("sslPolicyErrors == SslPolicyErrors.None. Thus returning true to validate certificate from clearstream.");
return true;
}
Console.WriteLine("Cert issues found. Attempting to load cacert pem from Clearstream.");
var privateChain = new X509Chain();
privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
var cert2 = new X509Certificate2(certificate);
var signerCert2 = new X509Certificate2(@".\Cert\ocapi-stb2_01014165_1000181-cacert.pem");
privateChain.ChainPolicy.ExtraStore.Add(signerCert2);
privateChain.Build(cert2);
var isValid = true;
Console.WriteLine("Validate Certificate chain manually.");
foreach (var chainStatus in privateChain.ChainStatus)
{
if (chainStatus.Status != X509ChainStatusFlags.NoError)
{
Console.WriteLine("chainStatus.Status != X509ChainStatusFlags.NoError");
isValid = false;
break;
}
}
Console.WriteLine($"Returning {isValid} as result of cert chain validation.");
if (isValid == false)
{
Console.WriteLine("Overriding false value for cert result with 'true'");
isValid = true;
}
return isValid;
}
/// <summary>
/// Main entry point for
/// </summary>
/// <param name="args"></param>
static async Task Main(string[] args)
{
try
{
// Console.WriteLine("Setting proxy to 'http://l7fwout.usinet.it:3128'");
// string resultString = string.Empty;
var errorOccured = false;
// // First create a proxy object
// var proxy = new WebProxy
// {
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
// BypassProxyOnLocal = false,
// UseDefaultCredentials = false,
// Credentials = CredentialCache.DefaultNetworkCredentials
// };
Console.WriteLine("Preparing the request...");
// check certificate chain
ServicePointManager.ServerCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
{
Console.WriteLine("Ssl Policy Errors:");
switch (sslPolicyErrors)
{
case SslPolicyErrors.None:
Console.WriteLine("No error in certificate found");
break;
case SslPolicyErrors.RemoteCertificateNotAvailable:
Console.WriteLine("RemoteCertificateNotAvailable");
break;
case SslPolicyErrors.RemoteCertificateNameMismatch:
Console.WriteLine("RemoteCertificateNameMismatch");
break;
case SslPolicyErrors.RemoteCertificateChainErrors:
Console.WriteLine("RemoteCertificateChainErrors");
break;
}
// call our validation logic
return ValidateServerCertificate(sender, certificate, chain, sslPolicyErrors);
};
// validate cert by calling a function
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
// first get the access token from clearstream API
var accessToken = await GetElibilityTokenAsync();
if (accessToken != null && !string.IsNullOrEmpty(accessToken.access_token))
{
Console.WriteLine("Received non null JWT token. Calling Playground Clearstream API");
Console.WriteLine($"Token: '{accessToken.access_token}'");
Console.WriteLine($"Refresh Token: {accessToken.refresh_token}");
Console.WriteLine($"Expires in: {accessToken.expires_in}");
// call the playground API
//resultString = await CallClearstreamPlaygroundApiAsync(accessToken);
//Console.WriteLine("For testing purposes, try to regain a new token based on the refresh token.");
//var refreshToken = await GetRefreshTokenAsync(accessToken);
//if (refreshToken != null)
//{
// Console.WriteLine("Received non null refresh token. Dumping details now:");
// Console.WriteLine($"Token: '{refreshToken.access_token}'");
// Console.WriteLine($"Refresh Token: {refreshToken.refresh_token}");
// Console.WriteLine($"Expires in: {refreshToken.expires_in}");
//}
// next try to call the FIRST real DI method and get the available templates
var templates = await GetAllTemplates(accessToken);
if (templates != null && templates.Count > 0)
{
Console.WriteLine("Dumping all received templates available for the account used:");
var firstTemplate = templates[0];
Console.WriteLine($"PartyId: {firstTemplate.partyId}");
}
Console.WriteLine("Successfully called Digital Instruments API.");
}
else
{
Console.WriteLine("Received empty JWT token. Aborting.");
errorOccured = true;
}
if (errorOccured)
{
Console.WriteLine("Clearstream VNext connectivity test completed with error(s).");
}
else
{
Console.WriteLine("Clearstream VNext connectivity test completed successfully.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Got Exception while running the connetivity check. Message {ex.Message}, Stacktrace: {ex.StackTrace}");
Console.WriteLine("Clearstream VNext connecivity check FAILED.");
}
}
}
}