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

[csharp-netcore] Configure the API key in string format for HttpSigningConfiguration #157

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5c28f79
Merge pull request #26 from OpenAPITools/master
code-lucidal58 Nov 2, 2020
f4028ff
Merge pull request #27 from OpenAPITools/master
code-lucidal58 Dec 17, 2020
5d1956b
Merge branch 'OpenAPITools:master' into master
code-lucidal58 May 11, 2021
2efa03e
Merge branch 'master' of ssh://github.com/OpenAPITools/openapi-genera…
vvb Aug 13, 2021
232cc89
Merge pull request #28 from CiscoM31/feature/refresh_master
vvb Aug 13, 2021
d3e3725
Merge branch 'master' of ssh://github.com/OpenAPITools/openapi-genera…
vvb Aug 18, 2021
91716ea
Merge pull request #42 from CiscoM31/refresh/master
vvb Aug 18, 2021
76f570e
Merge branch 'master' of ssh://github.com/OpenAPITools/openapi-genera…
vvb Aug 23, 2021
3ba948b
Merge pull request #43 from CiscoM31/refresh/master
vvb Aug 23, 2021
56f32d5
Merge branch 'master' of ssh://github.com/OpenAPITools/openapi-genera…
vvb Aug 25, 2021
058f491
Merge pull request #44 from CiscoM31/refresh/master
vvb Aug 25, 2021
b19bb30
Merge branch 'OpenAPITools:master' into master
vvb Sep 3, 2021
d58e4a2
Merge branch 'OpenAPITools:master' into master
sebastien-rosset Oct 11, 2021
7cd305c
Merge branch 'OpenAPITools:master' into master
sebastien-rosset Oct 12, 2021
6debc0b
Merge branch 'master' of ssh://github.com/OpenAPITools/openapi-genera…
vvb Mar 31, 2022
dfb40dc
Merge pull request #62 from CiscoM31/refresh/upstream
vvb Mar 31, 2022
a0e05b8
Merge pull request #78 from CiscoM31/feature/refresh_13_Jul_2022
vvb Jul 13, 2022
9264d06
Merge pull request #2 from CiscoM31/master
Ghufz Jun 8, 2023
de60f1e
HttpSigningConfiguration accept api key in string format.
Ghufz Jun 8, 2023
570bbbf
updated the sample code.
Ghufz Jun 13, 2023
ac58a25
removed the either or check for keyFilePath and KeyString
Ghufz Jun 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ namespace {{packageName}}.Client
/// </summary>
public string KeyFilePath { get; set; }

/// <summary>
/// Specify the API key in the form of a string, either configure the KeyString property or configure the KeyFilePath property.
/// </summary>
public string KeyString { get; set; }

/// <summary>
/// Gets the key pass phrase for password protected key
/// </summary>
Expand Down Expand Up @@ -108,6 +113,17 @@ namespace {{packageName}}.Client
var HttpSignedRequestHeader = new Dictionary<string, string>();
var HttpSignatureHeader = new Dictionary<string, string>();

//Read the api key from the file
if(string.IsNullOrEmpty(this.KeyString))
{
this.KeyString = ReadApiKeyFromFile(KeyFilePath);
}

if(string.IsNullOrEmpty(KeyString))
{
throw new Exception("No API key has been provided.");
}

if (HttpSigningHeader.Count == 0)
{
HttpSigningHeader.Add("(created)");
Expand Down Expand Up @@ -242,7 +258,7 @@ namespace {{packageName}}.Client
var headerValuesString = string.Join("\n", headerValuesList);
var signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
string headerSignatureStr = null;
var keyType = GetKeyType(KeyFilePath);
var keyType = GetKeyType(KeyString);

if (keyType == PrivateKeyType.RSA)
{
Expand Down Expand Up @@ -293,7 +309,7 @@ namespace {{packageName}}.Client

private string GetRSASignature(byte[] stringToSign)
{
RSA rsa = GetRSAProviderFromPemFile(KeyFilePath, KeyPassPhrase);
RSA rsa = GetRSAProviderFromPemFile(KeyString, KeyPassPhrase);
if (SigningAlgorithm == "RSASSA-PSS")
{
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pss);
Expand All @@ -317,14 +333,9 @@ namespace {{packageName}}.Client
/// <returns>ECDSA signature</returns>
private string GetECDSASignature(byte[] dataToSign)
{
if (!File.Exists(KeyFilePath))
{
throw new Exception("key file path does not exist.");
}

const string ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----";
const string ecKeyFooter = "-----END EC PRIVATE KEY-----";
var keyStr = File.ReadAllText(KeyFilePath);
var keyStr = KeyString;
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
var ecdsa = ECDsa.Create();
Expand Down Expand Up @@ -415,18 +426,13 @@ namespace {{packageName}}.Client
return derBytes.ToArray();
}

private RSACryptoServiceProvider GetRSAProviderFromPemFile(string pemfile, SecureString keyPassPhrase = null)
private RSACryptoServiceProvider GetRSAProviderFromPemFile(string keyString, SecureString keyPassPhrase = null)
{
const string pempubheader = "-----BEGIN PUBLIC KEY-----";
const string pempubfooter = "-----END PUBLIC KEY-----";
bool isPrivateKeyFile = true;
byte[] pemkey = null;

if (!File.Exists(pemfile))
{
throw new Exception("private key file does not exist.");
}
string pemstr = File.ReadAllText(pemfile).Trim();
string pemstr = keyString;

if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
{
Expand Down Expand Up @@ -713,13 +719,13 @@ namespace {{packageName}}.Client
/// <summary>
/// Detect the key type from the pem file.
/// </summary>
/// <param name="keyFilePath">key file path in pem format</param>
/// <param name="keyString">api key in string format</param>
/// <returns>Private Key Type</returns>
private PrivateKeyType GetKeyType(string keyFilePath)
private PrivateKeyType GetKeyType(string keyString)
{
if (!File.Exists(keyFilePath))
if (string.IsNullOrEmpty(keyString))
{
throw new Exception("Key file path does not exist.");
throw new Exception("No API key has been provided.");
}

const string ecPrivateKeyHeader = "BEGIN EC PRIVATE KEY";
Expand All @@ -729,7 +735,7 @@ namespace {{packageName}}.Client
//var pkcs8Header = "BEGIN PRIVATE KEY";
//var pkcs8Footer = "END PRIVATE KEY";
PrivateKeyType keyType;
var key = File.ReadAllLines(keyFilePath);
var key = KeyString.TrimEnd().Split('\n');

if (key[0].Contains(rsaPrivateKeyHeader) &&
key[key.Length - 1].ToString().Contains(rsaPrivateFooter))
Expand All @@ -747,6 +753,25 @@ namespace {{packageName}}.Client
}
return keyType;
}

/// <summary>
/// Read the api key form the api key file path and stored it in KeyString property.
/// </summary>
/// <param name="apiKeyFilePath">api key file path</param>
private string ReadApiKeyFromFile(string apiKeyFilePath)
{
string apiKeyString = null;
if(File.Exists(apiKeyFilePath))
{
apiKeyString = File.ReadAllText(apiKeyFilePath);
}
else
{
throw new Exception("Provided API key file path does not exists.");
}
return apiKeyString;
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public HttpSigningConfiguration()
/// </summary>
public string KeyFilePath { get; set; }

/// <summary>
/// Specify the API key in the form of a string, either configure the KeyString property or configure the KeyFilePath property.
/// </summary>
public string KeyString { get; set; }

/// <summary>
/// Gets the key pass phrase for password protected key
/// </summary>
Expand Down Expand Up @@ -116,6 +121,17 @@ internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string m
var HttpSignedRequestHeader = new Dictionary<string, string>();
var HttpSignatureHeader = new Dictionary<string, string>();

//Read the api key from the file
if(string.IsNullOrEmpty(this.KeyString))
{
this.KeyString = ReadApiKeyFromFile(KeyFilePath);
}

if(string.IsNullOrEmpty(KeyString))
{
throw new Exception("No API key has been provided.");
}

if (HttpSigningHeader.Count == 0)
{
HttpSigningHeader.Add("(created)");
Expand Down Expand Up @@ -250,7 +266,7 @@ internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string m
var headerValuesString = string.Join("\n", headerValuesList);
var signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
string headerSignatureStr = null;
var keyType = GetKeyType(KeyFilePath);
var keyType = GetKeyType(KeyString);

if (keyType == PrivateKeyType.RSA)
{
Expand Down Expand Up @@ -301,7 +317,7 @@ private int GetUnixTime(DateTime date2)

private string GetRSASignature(byte[] stringToSign)
{
RSA rsa = GetRSAProviderFromPemFile(KeyFilePath, KeyPassPhrase);
RSA rsa = GetRSAProviderFromPemFile(KeyString, KeyPassPhrase);
if (SigningAlgorithm == "RSASSA-PSS")
{
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pss);
Expand All @@ -325,14 +341,9 @@ private string GetRSASignature(byte[] stringToSign)
/// <returns>ECDSA signature</returns>
private string GetECDSASignature(byte[] dataToSign)
{
if (!File.Exists(KeyFilePath))
{
throw new Exception("key file path does not exist.");
}

const string ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----";
const string ecKeyFooter = "-----END EC PRIVATE KEY-----";
var keyStr = File.ReadAllText(KeyFilePath);
var keyStr = KeyString;
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
var ecdsa = ECDsa.Create();
Expand Down Expand Up @@ -423,18 +434,13 @@ private byte[] ConvertToECDSAANS1Format(byte[] signedBytes)
return derBytes.ToArray();
}

private RSACryptoServiceProvider GetRSAProviderFromPemFile(string pemfile, SecureString keyPassPhrase = null)
private RSACryptoServiceProvider GetRSAProviderFromPemFile(string keyString, SecureString keyPassPhrase = null)
{
const string pempubheader = "-----BEGIN PUBLIC KEY-----";
const string pempubfooter = "-----END PUBLIC KEY-----";
bool isPrivateKeyFile = true;
byte[] pemkey = null;

if (!File.Exists(pemfile))
{
throw new Exception("private key file does not exist.");
}
string pemstr = File.ReadAllText(pemfile).Trim();
string pemstr = keyString;

if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
{
Expand Down Expand Up @@ -721,13 +727,13 @@ private byte[] DecryptKey(byte[] cipherData, byte[] desKey, byte[] IV)
/// <summary>
/// Detect the key type from the pem file.
/// </summary>
/// <param name="keyFilePath">key file path in pem format</param>
/// <param name="keyString">api key in string format</param>
/// <returns>Private Key Type</returns>
private PrivateKeyType GetKeyType(string keyFilePath)
private PrivateKeyType GetKeyType(string keyString)
{
if (!File.Exists(keyFilePath))
if (string.IsNullOrEmpty(keyString))
{
throw new Exception("Key file path does not exist.");
throw new Exception("No API key has been provided.");
}

const string ecPrivateKeyHeader = "BEGIN EC PRIVATE KEY";
Expand All @@ -737,7 +743,7 @@ private PrivateKeyType GetKeyType(string keyFilePath)
//var pkcs8Header = "BEGIN PRIVATE KEY";
//var pkcs8Footer = "END PRIVATE KEY";
PrivateKeyType keyType;
var key = File.ReadAllLines(keyFilePath);
var key = KeyString.TrimEnd().Split('\n');

if (key[0].Contains(rsaPrivateKeyHeader) &&
key[key.Length - 1].ToString().Contains(rsaPrivateFooter))
Expand All @@ -755,6 +761,25 @@ private PrivateKeyType GetKeyType(string keyFilePath)
}
return keyType;
}

/// <summary>
/// Read the api key form the api key file path and stored it in KeyString property.
/// </summary>
/// <param name="apiKeyFilePath">api key file path</param>
private string ReadApiKeyFromFile(string apiKeyFilePath)
{
string apiKeyString = null;
if(File.Exists(apiKeyFilePath))
{
apiKeyString = File.ReadAllText(apiKeyFilePath);
}
else
{
throw new Exception("Provided API key file path does not exists.");
}
return apiKeyString;
}

#endregion
}
}
Loading