forked from loafle/openapi-generator-original
[C#][netcore] Rename HTTPSigningConfiguration.cs to HttpSigningConfiguration.cs (#7630)
* rename HTTPSigningConfiguration.cs to HttpSigningConfiguration.cs * update samples * minor change
This commit is contained in:
parent
b0fa00b860
commit
b208a311db
@ -641,7 +641,7 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
|
||||
supportingFiles.add(new SupportingFile("ClientUtils.mustache", clientPackageDir, "ClientUtils.cs"));
|
||||
supportingFiles.add(new SupportingFile("HttpMethod.mustache", clientPackageDir, "HttpMethod.cs"));
|
||||
if (ProcessUtils.hasHttpSignatureMethods(openAPI)) {
|
||||
supportingFiles.add(new SupportingFile("HTTPSigningConfiguration.mustache", clientPackageDir, "HTTPSigningConfiguration.cs"));
|
||||
supportingFiles.add(new SupportingFile("HttpSigningConfiguration.mustache", clientPackageDir, "HttpSigningConfiguration.cs"));
|
||||
}
|
||||
if (supportsAsync) {
|
||||
supportingFiles.add(new SupportingFile("IAsynchronousClient.mustache", clientPackageDir, "IAsynchronousClient.cs"));
|
||||
|
0
modules/openapi-generator/src/main/resources/csharp-netcore/ClientUtils.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/ClientUtils.mustache
vendored
Executable file → Normal file
@ -95,9 +95,9 @@ namespace {{packageName}}.Client
|
||||
{{#hasHttpSignatureMethods}}
|
||||
|
||||
/// <summary>
|
||||
/// HTTPSigning configuration
|
||||
/// HttpSigning configuration
|
||||
/// </summary>
|
||||
private HTTPSigningConfiguration _HTTPSigningConfiguration = null;
|
||||
private HttpSigningConfiguration _HttpSigningConfiguration = null;
|
||||
{{/hasHttpSignatureMethods}}
|
||||
#endregion Private Members
|
||||
|
||||
@ -472,12 +472,12 @@ namespace {{packageName}}.Client
|
||||
{{#hasHttpSignatureMethods}}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and Sets the HTTPSigningConfiuration
|
||||
/// Gets and Sets the HttpSigningConfiuration
|
||||
/// </summary>
|
||||
public HTTPSigningConfiguration HTTPSigningConfiguration
|
||||
public HttpSigningConfiguration HttpSigningConfiguration
|
||||
{
|
||||
get { return _HTTPSigningConfiguration; }
|
||||
set { _HTTPSigningConfiguration = value; }
|
||||
get { return _HttpSigningConfiguration; }
|
||||
set { _HttpSigningConfiguration = value; }
|
||||
}
|
||||
{{/hasHttpSignatureMethods}}
|
||||
|
||||
@ -558,7 +558,7 @@ namespace {{packageName}}.Client
|
||||
Password = second.Password ?? first.Password,
|
||||
AccessToken = second.AccessToken ?? first.AccessToken,
|
||||
{{#hasHttpSignatureMethods}}
|
||||
HTTPSigningConfiguration = second.HTTPSigningConfiguration ?? first.HTTPSigningConfiguration,
|
||||
HttpSigningConfiguration = second.HttpSigningConfiguration ?? first.HttpSigningConfiguration,
|
||||
{{/hasHttpSignatureMethods}}
|
||||
TempFolderPath = second.TempFolderPath ?? first.TempFolderPath,
|
||||
DateTimeFormat = second.DateTimeFormat ?? first.DateTimeFormat
|
||||
|
0
modules/openapi-generator/src/main/resources/csharp-netcore/HttpMethod.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/HttpMethod.mustache
vendored
Executable file → Normal file
@ -12,15 +12,15 @@ using System.Web;
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for HTTPSigning auth related parameter and methods
|
||||
/// Class for HttpSigning auth related parameter and methods
|
||||
/// </summary>
|
||||
public class HTTPSigningConfiguration
|
||||
public class HttpSigningConfiguration
|
||||
{
|
||||
#region
|
||||
/// <summary>
|
||||
/// Initailize the HashAlgorithm and SigningAlgorithm to default value
|
||||
/// </summary>
|
||||
public HTTPSigningConfiguration()
|
||||
public HttpSigningConfiguration()
|
||||
{
|
||||
HashAlgorithm = HashAlgorithmName.SHA256;
|
||||
SigningAlgorithm = "PKCS1-v15";
|
||||
@ -46,7 +46,7 @@ namespace {{packageName}}.Client
|
||||
/// <summary>
|
||||
/// Gets the HTTP signing header
|
||||
/// </summary>
|
||||
public List<string> HTTPSigningHeader { get; set; }
|
||||
public List<string> HttpSigningHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash algorithm sha256 or sha512
|
||||
@ -76,12 +76,11 @@ namespace {{packageName}}.Client
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Gets the Headers for HTTpSIgning
|
||||
/// Gets the Headers for HttpSigning
|
||||
/// </summary>
|
||||
/// <param name="basePath">Base path</param>
|
||||
/// <param name="method">HTTP method</param>
|
||||
/// <param name="path">Path</param>
|
||||
/// <param name="requestOptions">Request options</param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="requestOptions"></param>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string method, string path, RequestOptions requestOptions)
|
||||
{
|
||||
@ -103,12 +102,12 @@ namespace {{packageName}}.Client
|
||||
const string HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
//Hash table to store singed headers
|
||||
var httpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var httpSignatureHeader = new Dictionary<string, string>();
|
||||
var HttpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var HttpSignatureHeader = new Dictionary<string, string>();
|
||||
|
||||
if (HTTPSigningHeader.Count == 0)
|
||||
if (HttpSigningHeader.Count == 0)
|
||||
{
|
||||
HTTPSigningHeader.Add("(created)");
|
||||
HttpSigningHeader.Add("(created)");
|
||||
}
|
||||
|
||||
if (requestOptions.PathParameters != null)
|
||||
@ -167,37 +166,37 @@ namespace {{packageName}}.Client
|
||||
}
|
||||
|
||||
|
||||
foreach (var header in HTTPSigningHeader)
|
||||
foreach (var header in HttpSigningHeader)
|
||||
{
|
||||
if (header.Equals(HEADER_REQUEST_TARGET))
|
||||
{
|
||||
var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
|
||||
httpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
HttpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
}
|
||||
else if (header.Equals(HEADER_EXPIRES))
|
||||
{
|
||||
var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
|
||||
httpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DATE))
|
||||
{
|
||||
var utcDateTime = dateTime.ToString("r").ToString();
|
||||
httpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
httpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
}
|
||||
else if (header.Equals(HEADER_HOST))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
httpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
}
|
||||
else if (header.Equals(HEADER_CREATED))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DIGEST))
|
||||
{
|
||||
httpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
httpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
HttpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -206,7 +205,7 @@ namespace {{packageName}}.Client
|
||||
{
|
||||
if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
isHeaderFound = true;
|
||||
break;
|
||||
}
|
||||
@ -218,10 +217,10 @@ namespace {{packageName}}.Client
|
||||
}
|
||||
|
||||
}
|
||||
var headersKeysString = String.Join(" ", httpSignatureHeader.Keys);
|
||||
var headersKeysString = String.Join(" ", HttpSignatureHeader.Keys);
|
||||
var headerValuesList = new List<string>();
|
||||
|
||||
foreach (var keyVal in httpSignatureHeader)
|
||||
foreach (var keyVal in HttpSignatureHeader)
|
||||
{
|
||||
headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
|
||||
|
||||
@ -245,22 +244,22 @@ namespace {{packageName}}.Client
|
||||
KeyId, cryptographicScheme);
|
||||
|
||||
|
||||
if (httpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",created={0}", httpSignatureHeader[HEADER_CREATED]);
|
||||
authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
|
||||
}
|
||||
|
||||
if (httpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",expires={0}", httpSignatureHeader[HEADER_EXPIRES]);
|
||||
authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
|
||||
}
|
||||
|
||||
authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
|
||||
headersKeysString, headerSignatureStr);
|
||||
|
||||
httpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
|
||||
return httpSignedRequestHeader;
|
||||
return HttpSignedRequestHeader;
|
||||
}
|
||||
|
||||
private byte[] GetStringHash(string hashName, string stringToBeHashed)
|
||||
@ -314,16 +313,16 @@ namespace {{packageName}}.Client
|
||||
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
|
||||
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
|
||||
var ecdsa = ECDsa.Create();
|
||||
var bytCount = 0;
|
||||
|
||||
#if (NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0)
|
||||
var byteCount = 0;
|
||||
if (configuration.KeyPassPhrase != null)
|
||||
{
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out byteCount);
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out bytCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out byteCount);
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out bytCount);
|
||||
}
|
||||
var signedBytes = ecdsa.SignHash(dataToSign);
|
||||
var derBytes = ConvertToECDSAANS1Format(signedBytes);
|
||||
@ -688,6 +687,7 @@ namespace {{packageName}}.Client
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
|
||||
/*this type of key can hold many type different types of private key, but here due lack of pem header
|
||||
Considering this as EC key
|
||||
*/
|
0
modules/openapi-generator/src/main/resources/csharp-netcore/IAsynchronousClient.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/IAsynchronousClient.mustache
vendored
Executable file → Normal file
@ -99,9 +99,9 @@ namespace {{packageName}}.Client
|
||||
{{#hasHttpSignatureMethods}}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTPSigning configuration
|
||||
/// Gets the HttpSigning configuration
|
||||
/// </summary>
|
||||
HTTPSigningConfiguration HTTPSigningConfiguration { get; }
|
||||
HttpSigningConfiguration HttpSigningConfiguration { get; }
|
||||
{{/hasHttpSignatureMethods}}
|
||||
}
|
||||
}
|
||||
|
0
modules/openapi-generator/src/main/resources/csharp-netcore/ISynchronousClient.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/ISynchronousClient.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/Multimap.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/Multimap.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/RequestOptions.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/RequestOptions.mustache
vendored
Executable file → Normal file
@ -370,9 +370,9 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isHttpSignature}}
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -565,9 +565,9 @@ namespace {{packageName}}.{{apiPackage}}
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isHttpSignature}}
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
|
0
modules/openapi-generator/src/main/resources/csharp-netcore/git_push.sh.mustache
vendored
Executable file → Normal file
0
modules/openapi-generator/src/main/resources/csharp-netcore/git_push.sh.mustache
vendored
Executable file → Normal file
@ -104,8 +104,8 @@ src/Org.OpenAPITools/Client/ClientUtils.cs
|
||||
src/Org.OpenAPITools/Client/Configuration.cs
|
||||
src/Org.OpenAPITools/Client/ExceptionFactory.cs
|
||||
src/Org.OpenAPITools/Client/GlobalConfiguration.cs
|
||||
src/Org.OpenAPITools/Client/HTTPSigningConfiguration.cs
|
||||
src/Org.OpenAPITools/Client/HttpMethod.cs
|
||||
src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
|
||||
src/Org.OpenAPITools/Client/IApiAccessor.cs
|
||||
src/Org.OpenAPITools/Client/IAsynchronousClient.cs
|
||||
src/Org.OpenAPITools/Client/IReadableConfiguration.cs
|
||||
|
@ -604,9 +604,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -685,9 +685,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -891,9 +891,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "status", status));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -973,9 +973,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "status", status));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1052,9 +1052,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "tags", tags));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1134,9 +1134,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "tags", tags));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1331,9 +1331,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1412,9 +1412,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
|
@ -91,9 +91,9 @@ namespace Org.OpenAPITools.Client
|
||||
private IList<IReadOnlyDictionary<string, object>> _servers;
|
||||
|
||||
/// <summary>
|
||||
/// HTTPSigning configuration
|
||||
/// HttpSigning configuration
|
||||
/// </summary>
|
||||
private HTTPSigningConfiguration _HTTPSigningConfiguration = null;
|
||||
private HttpSigningConfiguration _HttpSigningConfiguration = null;
|
||||
#endregion Private Members
|
||||
|
||||
#region Constructors
|
||||
@ -488,12 +488,12 @@ namespace Org.OpenAPITools.Client
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and Sets the HTTPSigningConfiuration
|
||||
/// Gets and Sets the HttpSigningConfiuration
|
||||
/// </summary>
|
||||
public HTTPSigningConfiguration HTTPSigningConfiguration
|
||||
public HttpSigningConfiguration HttpSigningConfiguration
|
||||
{
|
||||
get { return _HTTPSigningConfiguration; }
|
||||
set { _HTTPSigningConfiguration = value; }
|
||||
get { return _HttpSigningConfiguration; }
|
||||
set { _HttpSigningConfiguration = value; }
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
@ -566,7 +566,7 @@ namespace Org.OpenAPITools.Client
|
||||
Username = second.Username ?? first.Username,
|
||||
Password = second.Password ?? first.Password,
|
||||
AccessToken = second.AccessToken ?? first.AccessToken,
|
||||
HTTPSigningConfiguration = second.HTTPSigningConfiguration ?? first.HTTPSigningConfiguration,
|
||||
HttpSigningConfiguration = second.HttpSigningConfiguration ?? first.HttpSigningConfiguration,
|
||||
TempFolderPath = second.TempFolderPath ?? first.TempFolderPath,
|
||||
DateTimeFormat = second.DateTimeFormat ?? first.DateTimeFormat
|
||||
};
|
||||
|
@ -12,15 +12,15 @@ using System.Web;
|
||||
namespace Org.OpenAPITools.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for HTTPSigning auth related parameter and methods
|
||||
/// Class for HttpSigning auth related parameter and methods
|
||||
/// </summary>
|
||||
public class HTTPSigningConfiguration
|
||||
public class HttpSigningConfiguration
|
||||
{
|
||||
#region
|
||||
/// <summary>
|
||||
/// Initailize the HashAlgorithm and SigningAlgorithm to default value
|
||||
/// </summary>
|
||||
public HTTPSigningConfiguration()
|
||||
public HttpSigningConfiguration()
|
||||
{
|
||||
HashAlgorithm = HashAlgorithmName.SHA256;
|
||||
SigningAlgorithm = "PKCS1-v15";
|
||||
@ -46,7 +46,7 @@ namespace Org.OpenAPITools.Client
|
||||
/// <summary>
|
||||
/// Gets the HTTP signing header
|
||||
/// </summary>
|
||||
public List<string> HTTPSigningHeader { get; set; }
|
||||
public List<string> HttpSigningHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash algorithm sha256 or sha512
|
||||
@ -76,12 +76,11 @@ namespace Org.OpenAPITools.Client
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Gets the Headers for HTTpSIgning
|
||||
/// Gets the Headers for HttpSigning
|
||||
/// </summary>
|
||||
/// <param name="basePath">Base path</param>
|
||||
/// <param name="method">HTTP method</param>
|
||||
/// <param name="path">Path</param>
|
||||
/// <param name="requestOptions">Request options</param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="requestOptions"></param>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string method, string path, RequestOptions requestOptions)
|
||||
{
|
||||
@ -103,12 +102,12 @@ namespace Org.OpenAPITools.Client
|
||||
const string HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
//Hash table to store singed headers
|
||||
var httpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var httpSignatureHeader = new Dictionary<string, string>();
|
||||
var HttpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var HttpSignatureHeader = new Dictionary<string, string>();
|
||||
|
||||
if (HTTPSigningHeader.Count == 0)
|
||||
if (HttpSigningHeader.Count == 0)
|
||||
{
|
||||
HTTPSigningHeader.Add("(created)");
|
||||
HttpSigningHeader.Add("(created)");
|
||||
}
|
||||
|
||||
if (requestOptions.PathParameters != null)
|
||||
@ -167,37 +166,37 @@ namespace Org.OpenAPITools.Client
|
||||
}
|
||||
|
||||
|
||||
foreach (var header in HTTPSigningHeader)
|
||||
foreach (var header in HttpSigningHeader)
|
||||
{
|
||||
if (header.Equals(HEADER_REQUEST_TARGET))
|
||||
{
|
||||
var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
|
||||
httpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
HttpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
}
|
||||
else if (header.Equals(HEADER_EXPIRES))
|
||||
{
|
||||
var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
|
||||
httpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DATE))
|
||||
{
|
||||
var utcDateTime = dateTime.ToString("r").ToString();
|
||||
httpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
httpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
}
|
||||
else if (header.Equals(HEADER_HOST))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
httpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
}
|
||||
else if (header.Equals(HEADER_CREATED))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DIGEST))
|
||||
{
|
||||
httpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
httpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
HttpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -206,7 +205,7 @@ namespace Org.OpenAPITools.Client
|
||||
{
|
||||
if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
isHeaderFound = true;
|
||||
break;
|
||||
}
|
||||
@ -218,10 +217,10 @@ namespace Org.OpenAPITools.Client
|
||||
}
|
||||
|
||||
}
|
||||
var headersKeysString = String.Join(" ", httpSignatureHeader.Keys);
|
||||
var headersKeysString = String.Join(" ", HttpSignatureHeader.Keys);
|
||||
var headerValuesList = new List<string>();
|
||||
|
||||
foreach (var keyVal in httpSignatureHeader)
|
||||
foreach (var keyVal in HttpSignatureHeader)
|
||||
{
|
||||
headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
|
||||
|
||||
@ -245,22 +244,22 @@ namespace Org.OpenAPITools.Client
|
||||
KeyId, cryptographicScheme);
|
||||
|
||||
|
||||
if (httpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",created={0}", httpSignatureHeader[HEADER_CREATED]);
|
||||
authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
|
||||
}
|
||||
|
||||
if (httpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",expires={0}", httpSignatureHeader[HEADER_EXPIRES]);
|
||||
authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
|
||||
}
|
||||
|
||||
authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
|
||||
headersKeysString, headerSignatureStr);
|
||||
|
||||
httpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
|
||||
return httpSignedRequestHeader;
|
||||
return HttpSignedRequestHeader;
|
||||
}
|
||||
|
||||
private byte[] GetStringHash(string hashName, string stringToBeHashed)
|
||||
@ -314,16 +313,16 @@ namespace Org.OpenAPITools.Client
|
||||
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
|
||||
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
|
||||
var ecdsa = ECDsa.Create();
|
||||
var bytCount = 0;
|
||||
|
||||
#if (NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0)
|
||||
var byteCount = 0;
|
||||
if (configuration.KeyPassPhrase != null)
|
||||
{
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out byteCount);
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out bytCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out byteCount);
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out bytCount);
|
||||
}
|
||||
var signedBytes = ecdsa.SignHash(dataToSign);
|
||||
var derBytes = ConvertToECDSAANS1Format(signedBytes);
|
||||
@ -688,6 +687,7 @@ namespace Org.OpenAPITools.Client
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
|
||||
/*this type of key can hold many type different types of private key, but here due lack of pem header
|
||||
Considering this as EC key
|
||||
*/
|
||||
|
@ -0,0 +1,706 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace Org.OpenAPITools.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for HttpSigning auth related parameter and methods
|
||||
/// </summary>
|
||||
public class HttpSigningConfiguration
|
||||
{
|
||||
#region
|
||||
/// <summary>
|
||||
/// Initailize the HashAlgorithm and SigningAlgorithm to default value
|
||||
/// </summary>
|
||||
public HttpSigningConfiguration()
|
||||
{
|
||||
HashAlgorithm = HashAlgorithmName.SHA256;
|
||||
SigningAlgorithm = "PKCS1-v15";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
///Gets the Api keyId
|
||||
/// </summary>
|
||||
public string KeyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Key file path
|
||||
/// </summary>
|
||||
public string KeyFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key pass phrase for password protected key
|
||||
/// </summary>
|
||||
public SecureString KeyPassPhrase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP signing header
|
||||
/// </summary>
|
||||
public List<string> HttpSigningHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash algorithm sha256 or sha512
|
||||
/// </summary>
|
||||
public HashAlgorithmName HashAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the signing algorithm
|
||||
/// </summary>
|
||||
public string SigningAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Signature validaty period in seconds
|
||||
/// </summary>
|
||||
public int SignatureValidityPeriod { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region enum
|
||||
private enum PrivateKeyType
|
||||
{
|
||||
None = 0,
|
||||
RSA = 1,
|
||||
ECDSA = 2,
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Gets the Headers for HttpSigning
|
||||
/// </summary>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="requestOptions"></param>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string method, string path, RequestOptions requestOptions)
|
||||
{
|
||||
const string HEADER_REQUEST_TARGET = "(request-target)";
|
||||
//The time when the HTTP signature expires. The API server should reject HTTP requests
|
||||
//that have expired.
|
||||
const string HEADER_EXPIRES = "(expires)";
|
||||
//The 'Date' header.
|
||||
const string HEADER_DATE = "Date";
|
||||
//The 'Host' header.
|
||||
const string HEADER_HOST = "Host";
|
||||
//The time when the HTTP signature was generated.
|
||||
const string HEADER_CREATED = "(created)";
|
||||
//When the 'Digest' header is included in the HTTP signature, the client automatically
|
||||
//computes the digest of the HTTP request body, per RFC 3230.
|
||||
const string HEADER_DIGEST = "Digest";
|
||||
//The 'Authorization' header is automatically generated by the client. It includes
|
||||
//the list of signed headers and a base64-encoded signature.
|
||||
const string HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
//Hash table to store singed headers
|
||||
var HttpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var HttpSignatureHeader = new Dictionary<string, string>();
|
||||
|
||||
if (HttpSigningHeader.Count == 0)
|
||||
{
|
||||
HttpSigningHeader.Add("(created)");
|
||||
}
|
||||
|
||||
if (requestOptions.PathParameters != null)
|
||||
{
|
||||
foreach (var pathParam in requestOptions.PathParameters)
|
||||
{
|
||||
var tempPath = path.Replace(pathParam.Key, "0");
|
||||
path = string.Format(tempPath, pathParam.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var httpValues = HttpUtility.ParseQueryString(String.Empty);
|
||||
foreach (var parameter in requestOptions.QueryParameters)
|
||||
{
|
||||
if (parameter.Value.Count > 1)
|
||||
{ // array
|
||||
foreach (var value in parameter.Value)
|
||||
{
|
||||
httpValues.Add(parameter.Key + "[]", value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
httpValues.Add(parameter.Key, parameter.Value[0]);
|
||||
|
||||
}
|
||||
}
|
||||
var uriBuilder = new UriBuilder(string.Concat(basePath, path));
|
||||
uriBuilder.Query = httpValues.ToString();
|
||||
|
||||
var dateTime = DateTime.Now;
|
||||
String Digest = String.Empty;
|
||||
|
||||
//get the body
|
||||
string requestBody = string.Empty;
|
||||
if (requestOptions.Data != null)
|
||||
{
|
||||
var serializerSettings = new JsonSerializerSettings();
|
||||
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
requestBody = JsonConvert.SerializeObject(requestOptions.Data, serializerSettings);
|
||||
}
|
||||
|
||||
if (HashAlgorithm == HashAlgorithmName.SHA256)
|
||||
{
|
||||
var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
|
||||
Digest = string.Format("SHA-256={0}", Convert.ToBase64String(bodyDigest));
|
||||
}
|
||||
else if (HashAlgorithm == HashAlgorithmName.SHA512)
|
||||
{
|
||||
var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
|
||||
Digest = string.Format("SHA-512={0}", Convert.ToBase64String(bodyDigest));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(string.Format("{0} not supported", HashAlgorithm));
|
||||
}
|
||||
|
||||
|
||||
foreach (var header in HttpSigningHeader)
|
||||
{
|
||||
if (header.Equals(HEADER_REQUEST_TARGET))
|
||||
{
|
||||
var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
|
||||
HttpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
}
|
||||
else if (header.Equals(HEADER_EXPIRES))
|
||||
{
|
||||
var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DATE))
|
||||
{
|
||||
var utcDateTime = dateTime.ToString("r").ToString();
|
||||
HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
}
|
||||
else if (header.Equals(HEADER_HOST))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
}
|
||||
else if (header.Equals(HEADER_CREATED))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DIGEST))
|
||||
{
|
||||
HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
HttpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isHeaderFound = false;
|
||||
foreach (var item in requestOptions.HeaderParameters)
|
||||
{
|
||||
if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
isHeaderFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isHeaderFound)
|
||||
{
|
||||
throw new Exception(string.Format("Cannot sign HTTP request.Request does not contain the {0} header.",header));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
var headersKeysString = String.Join(" ", HttpSignatureHeader.Keys);
|
||||
var headerValuesList = new List<string>();
|
||||
|
||||
foreach (var keyVal in HttpSignatureHeader)
|
||||
{
|
||||
headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
|
||||
|
||||
}
|
||||
//Concatinate headers value separated by new line
|
||||
var headerValuesString = string.Join("\n", headerValuesList);
|
||||
var signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
|
||||
string headerSignatureStr = null;
|
||||
var keyType = GetKeyType(KeyFilePath);
|
||||
|
||||
if (keyType == PrivateKeyType.RSA)
|
||||
{
|
||||
headerSignatureStr = GetRSASignature(signatureStringHash);
|
||||
}
|
||||
else if (keyType == PrivateKeyType.ECDSA)
|
||||
{
|
||||
headerSignatureStr = GetECDSASignature(signatureStringHash);
|
||||
}
|
||||
var cryptographicScheme = "hs2019";
|
||||
var authorizationHeaderValue = string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\"",
|
||||
KeyId, cryptographicScheme);
|
||||
|
||||
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
|
||||
}
|
||||
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
|
||||
}
|
||||
|
||||
authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
|
||||
headersKeysString, headerSignatureStr);
|
||||
|
||||
HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
|
||||
return HttpSignedRequestHeader;
|
||||
}
|
||||
|
||||
private byte[] GetStringHash(string hashName, string stringToBeHashed)
|
||||
{
|
||||
var hashAlgorithm = System.Security.Cryptography.HashAlgorithm.Create(hashName);
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(stringToBeHashed);
|
||||
var stringHash = hashAlgorithm.ComputeHash(bytes);
|
||||
return stringHash;
|
||||
}
|
||||
|
||||
private int GetUnixTime(DateTime date2)
|
||||
{
|
||||
DateTime date1 = new DateTime(1970, 01, 01);
|
||||
TimeSpan timeSpan = date2 - date1;
|
||||
return (int)timeSpan.TotalSeconds;
|
||||
}
|
||||
|
||||
private string GetRSASignature(byte[] stringToSign)
|
||||
{
|
||||
RSA rsa = GetRSAProviderFromPemFile(KeyFilePath, KeyPassPhrase);
|
||||
if (SigningAlgorithm == "RSASSA-PSS")
|
||||
{
|
||||
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pss);
|
||||
return Convert.ToBase64String(signedbytes);
|
||||
|
||||
}
|
||||
else if (SigningAlgorithm == "PKCS1-v15")
|
||||
{
|
||||
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pkcs1);
|
||||
return Convert.ToBase64String(signedbytes);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ECDSA signature
|
||||
/// </summary>
|
||||
/// <param name="dataToSign"></param>
|
||||
/// <returns></returns>
|
||||
private string GetECDSASignature(byte[] dataToSign)
|
||||
{
|
||||
if (!File.Exists(KeyFilePath))
|
||||
{
|
||||
throw new Exception("key file path does not exist.");
|
||||
}
|
||||
|
||||
var ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----";
|
||||
var ecKeyFooter = "-----END EC PRIVATE KEY-----";
|
||||
var keyStr = File.ReadAllText(KeyFilePath);
|
||||
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
|
||||
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
|
||||
var ecdsa = ECDsa.Create();
|
||||
var bytCount = 0;
|
||||
|
||||
#if (NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0)
|
||||
if (configuration.KeyPassPhrase != null)
|
||||
{
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out bytCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out bytCount);
|
||||
}
|
||||
var signedBytes = ecdsa.SignHash(dataToSign);
|
||||
var derBytes = ConvertToECDSAANS1Format(signedBytes);
|
||||
var signedString = System.Convert.ToBase64String(derBytes);
|
||||
|
||||
return signedString;
|
||||
#else
|
||||
throw new Exception("ECDSA signing is supported only on NETCOREAPP3_0 and above");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private byte[] ConvertToECDSAANS1Format(byte[] signedBytes)
|
||||
{
|
||||
var derBytes = new List<byte>();
|
||||
byte derLength = 68; //default lenght for ECDSA code signinged bit 0x44
|
||||
byte rbytesLength = 32; //R length 0x20
|
||||
byte sbytesLength = 32; //S length 0x20
|
||||
var rBytes = new List<byte>();
|
||||
var sBytes = new List<byte>();
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
rBytes.Add(signedBytes[i]);
|
||||
}
|
||||
for (int i = 32; i < 64; i++)
|
||||
{
|
||||
sBytes.Add(signedBytes[i]);
|
||||
}
|
||||
|
||||
if (rBytes[0] > 0x7F)
|
||||
{
|
||||
derLength++;
|
||||
rbytesLength++;
|
||||
var tempBytes = new List<byte>();
|
||||
tempBytes.AddRange(rBytes);
|
||||
rBytes.Clear();
|
||||
rBytes.Add(0x00);
|
||||
rBytes.AddRange(tempBytes);
|
||||
}
|
||||
|
||||
if (sBytes[0] > 0x7F)
|
||||
{
|
||||
derLength++;
|
||||
sbytesLength++;
|
||||
var tempBytes = new List<byte>();
|
||||
tempBytes.AddRange(sBytes);
|
||||
sBytes.Clear();
|
||||
sBytes.Add(0x00);
|
||||
sBytes.AddRange(tempBytes);
|
||||
|
||||
}
|
||||
|
||||
derBytes.Add(48); //start of the sequence 0x30
|
||||
derBytes.Add(derLength); //total length r lenth, type and r bytes
|
||||
|
||||
derBytes.Add(2); //tag for integer
|
||||
derBytes.Add(rbytesLength); //length of r
|
||||
derBytes.AddRange(rBytes);
|
||||
|
||||
derBytes.Add(2); //tag for integer
|
||||
derBytes.Add(sbytesLength); //length of s
|
||||
derBytes.AddRange(sBytes);
|
||||
return derBytes.ToArray();
|
||||
}
|
||||
|
||||
private RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile, SecureString keyPassPharse = 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();
|
||||
|
||||
if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
|
||||
{
|
||||
isPrivateKeyFile = false;
|
||||
}
|
||||
|
||||
if (isPrivateKeyFile)
|
||||
{
|
||||
pemkey = ConvertPrivateKeyToBytes(pemstr, keyPassPharse);
|
||||
if (pemkey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return DecodeRSAPrivateKey(pemkey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private byte[] ConvertPrivateKeyToBytes(String instr, SecureString keyPassPharse = null)
|
||||
{
|
||||
const String pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
|
||||
const String pemprivfooter = "-----END RSA PRIVATE KEY-----";
|
||||
String pemstr = instr.Trim();
|
||||
byte[] binkey;
|
||||
|
||||
if (!pemstr.StartsWith(pemprivheader) || !pemstr.EndsWith(pemprivfooter))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(pemstr);
|
||||
sb.Replace(pemprivheader, "");
|
||||
sb.Replace(pemprivfooter, "");
|
||||
String pvkstr = sb.ToString().Trim();
|
||||
|
||||
try
|
||||
{ // if there are no PEM encryption info lines, this is an UNencrypted PEM private key
|
||||
binkey = Convert.FromBase64String(pvkstr);
|
||||
return binkey;
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{
|
||||
StringReader str = new StringReader(pvkstr);
|
||||
|
||||
//-------- read PEM encryption info. lines and extract salt -----
|
||||
if (!str.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED"))
|
||||
return null;
|
||||
String saltline = str.ReadLine();
|
||||
if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,"))
|
||||
return null;
|
||||
String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim();
|
||||
byte[] salt = new byte[saltstr.Length / 2];
|
||||
for (int i = 0; i < salt.Length; i++)
|
||||
salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16);
|
||||
if (!(str.ReadLine() == ""))
|
||||
return null;
|
||||
|
||||
//------ remaining b64 data is encrypted RSA key ----
|
||||
String encryptedstr = str.ReadToEnd();
|
||||
|
||||
try
|
||||
{ //should have b64 encrypted RSA key now
|
||||
binkey = Convert.FromBase64String(encryptedstr);
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{ //data is not in base64 fromat
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] deskey = GetEncryptedKey(salt, keyPassPharse, 1, 2); // count=1 (for OpenSSL implementation); 2 iterations to get at least 24 bytes
|
||||
if (deskey == null)
|
||||
return null;
|
||||
|
||||
//------ Decrypt the encrypted 3des-encrypted RSA private key ------
|
||||
byte[] rsakey = DecryptKey(binkey, deskey, salt); //OpenSSL uses salt value in PEM header also as 3DES IV
|
||||
return rsakey;
|
||||
}
|
||||
}
|
||||
|
||||
private RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
|
||||
{
|
||||
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
|
||||
|
||||
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
|
||||
MemoryStream mem = new MemoryStream(privkey);
|
||||
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
|
||||
byte bt = 0;
|
||||
ushort twobytes = 0;
|
||||
int elems = 0;
|
||||
try
|
||||
{
|
||||
twobytes = binr.ReadUInt16();
|
||||
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
|
||||
binr.ReadByte(); //advance 1 byte
|
||||
else if (twobytes == 0x8230)
|
||||
binr.ReadInt16(); //advance 2 bytes
|
||||
else
|
||||
return null;
|
||||
|
||||
twobytes = binr.ReadUInt16();
|
||||
if (twobytes != 0x0102) //version number
|
||||
return null;
|
||||
bt = binr.ReadByte();
|
||||
if (bt != 0x00)
|
||||
return null;
|
||||
|
||||
//------ all private key components are Integer sequences ----
|
||||
elems = GetIntegerSize(binr);
|
||||
MODULUS = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
E = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
D = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
P = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
Q = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
DP = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
DQ = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
IQ = binr.ReadBytes(elems);
|
||||
|
||||
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
RSAParameters RSAparams = new RSAParameters();
|
||||
RSAparams.Modulus = MODULUS;
|
||||
RSAparams.Exponent = E;
|
||||
RSAparams.D = D;
|
||||
RSAparams.P = P;
|
||||
RSAparams.Q = Q;
|
||||
RSAparams.DP = DP;
|
||||
RSAparams.DQ = DQ;
|
||||
RSAparams.InverseQ = IQ;
|
||||
RSA.ImportParameters(RSAparams);
|
||||
return RSA;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally { binr.Close(); }
|
||||
}
|
||||
|
||||
private int GetIntegerSize(BinaryReader binr)
|
||||
{
|
||||
byte bt = 0;
|
||||
byte lowbyte = 0x00;
|
||||
byte highbyte = 0x00;
|
||||
int count = 0;
|
||||
bt = binr.ReadByte();
|
||||
if (bt != 0x02) //expect integer
|
||||
return 0;
|
||||
bt = binr.ReadByte();
|
||||
|
||||
if (bt == 0x81)
|
||||
count = binr.ReadByte(); // data size in next byte
|
||||
else if (bt == 0x82)
|
||||
{
|
||||
highbyte = binr.ReadByte(); // data size in next 2 bytes
|
||||
lowbyte = binr.ReadByte();
|
||||
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
|
||||
count = BitConverter.ToInt32(modint, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = bt; // we already have the data size
|
||||
}
|
||||
while (binr.ReadByte() == 0x00)
|
||||
{ //remove high order zeros in data
|
||||
count -= 1;
|
||||
}
|
||||
binr.BaseStream.Seek(-1, SeekOrigin.Current);
|
||||
//last ReadByte wasn't a removed zero, so back up a byte
|
||||
return count;
|
||||
}
|
||||
|
||||
private byte[] GetEncryptedKey(byte[] salt, SecureString secpswd, int count, int miter)
|
||||
{
|
||||
IntPtr unmanagedPswd = IntPtr.Zero;
|
||||
int HASHLENGTH = 16; //MD5 bytes
|
||||
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store contatenated Mi hashed results
|
||||
|
||||
byte[] psbytes = new byte[secpswd.Length];
|
||||
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
|
||||
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
|
||||
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
|
||||
|
||||
// --- contatenate salt and pswd bytes into fixed data array ---
|
||||
byte[] data00 = new byte[psbytes.Length + salt.Length];
|
||||
Array.Copy(psbytes, data00, psbytes.Length); //copy the pswd bytes
|
||||
Array.Copy(salt, 0, data00, psbytes.Length, salt.Length); //concatenate the salt bytes
|
||||
|
||||
// ---- do multi-hashing and contatenate results D1, D2 ... into keymaterial bytes ----
|
||||
MD5 md5 = new MD5CryptoServiceProvider();
|
||||
byte[] result = null;
|
||||
byte[] hashtarget = new byte[HASHLENGTH + data00.Length]; //fixed length initial hashtarget
|
||||
|
||||
for (int j = 0; j < miter; j++)
|
||||
{
|
||||
// ---- Now hash consecutively for count times ------
|
||||
if (j == 0)
|
||||
result = data00; //initialize
|
||||
else
|
||||
{
|
||||
Array.Copy(result, hashtarget, result.Length);
|
||||
Array.Copy(data00, 0, hashtarget, result.Length, data00.Length);
|
||||
result = hashtarget;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
result = md5.ComputeHash(result);
|
||||
Array.Copy(result, 0, keymaterial, j * HASHLENGTH, result.Length); //contatenate to keymaterial
|
||||
}
|
||||
byte[] deskey = new byte[24];
|
||||
Array.Copy(keymaterial, deskey, deskey.Length);
|
||||
|
||||
Array.Clear(psbytes, 0, psbytes.Length);
|
||||
Array.Clear(data00, 0, data00.Length);
|
||||
Array.Clear(result, 0, result.Length);
|
||||
Array.Clear(hashtarget, 0, hashtarget.Length);
|
||||
Array.Clear(keymaterial, 0, keymaterial.Length);
|
||||
return deskey;
|
||||
}
|
||||
|
||||
private byte[] DecryptKey(byte[] cipherData, byte[] desKey, byte[] IV)
|
||||
{
|
||||
MemoryStream memst = new MemoryStream();
|
||||
TripleDES alg = TripleDES.Create();
|
||||
alg.Key = desKey;
|
||||
alg.IV = IV;
|
||||
try
|
||||
{
|
||||
CryptoStream cs = new CryptoStream(memst, alg.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(cipherData, 0, cipherData.Length);
|
||||
cs.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
byte[] decryptedData = memst.ToArray();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detect the key type from the pem file.
|
||||
/// </summary>
|
||||
/// <param name="keyFilePath">key file path in pem format</param>
|
||||
/// <returns></returns>
|
||||
private PrivateKeyType GetKeyType(string keyFilePath)
|
||||
{
|
||||
if (!File.Exists(keyFilePath))
|
||||
{
|
||||
throw new Exception("Key file path does not exist.");
|
||||
}
|
||||
|
||||
var ecPrivateKeyHeader = "BEGIN EC PRIVATE KEY";
|
||||
var ecPrivateKeyFooter = "END EC PRIVATE KEY";
|
||||
var rsaPrivateKeyHeader = "BEGIN RSA PRIVATE KEY";
|
||||
var rsaPrivateFooter = "END RSA PRIVATE KEY";
|
||||
var pkcs8Header = "BEGIN PRIVATE KEY";
|
||||
var pkcs8Footer = "END PRIVATE KEY";
|
||||
var keyType = PrivateKeyType.None;
|
||||
var key = File.ReadAllLines(keyFilePath);
|
||||
|
||||
if (key[0].ToString().Contains(rsaPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(rsaPrivateFooter))
|
||||
{
|
||||
keyType = PrivateKeyType.RSA;
|
||||
}
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
keyType = PrivateKeyType.ECDSA;
|
||||
}
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
|
||||
/*this type of key can hold many type different types of private key, but here due lack of pem header
|
||||
Considering this as EC key
|
||||
*/
|
||||
//TODO :- update the key based on oid
|
||||
keyType = PrivateKeyType.ECDSA;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Either the key is invalid or key is not supported");
|
||||
|
||||
}
|
||||
return keyType;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -106,8 +106,8 @@ namespace Org.OpenAPITools.Client
|
||||
X509CertificateCollection ClientCertificates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTPSigning configuration
|
||||
/// Gets the HttpSigning configuration
|
||||
/// </summary>
|
||||
HTTPSigningConfiguration HTTPSigningConfiguration { get; }
|
||||
HttpSigningConfiguration HttpSigningConfiguration { get; }
|
||||
}
|
||||
}
|
||||
|
@ -104,8 +104,8 @@ src/Org.OpenAPITools/Client/ClientUtils.cs
|
||||
src/Org.OpenAPITools/Client/Configuration.cs
|
||||
src/Org.OpenAPITools/Client/ExceptionFactory.cs
|
||||
src/Org.OpenAPITools/Client/GlobalConfiguration.cs
|
||||
src/Org.OpenAPITools/Client/HTTPSigningConfiguration.cs
|
||||
src/Org.OpenAPITools/Client/HttpMethod.cs
|
||||
src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
|
||||
src/Org.OpenAPITools/Client/IApiAccessor.cs
|
||||
src/Org.OpenAPITools/Client/IAsynchronousClient.cs
|
||||
src/Org.OpenAPITools/Client/IReadableConfiguration.cs
|
||||
|
@ -604,9 +604,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -685,9 +685,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "POST", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -891,9 +891,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "status", status));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -973,9 +973,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "status", status));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByStatus", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1052,9 +1052,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "tags", tags));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1134,9 +1134,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.QueryParameters.Add(Org.OpenAPITools.Client.ClientUtils.ParameterToMultiMap("csv", "tags", tags));
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "GET", "/pet/findByTags", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1331,9 +1331,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
@ -1412,9 +1412,9 @@ namespace Org.OpenAPITools.Api
|
||||
localVarRequestOptions.Data = pet;
|
||||
|
||||
// authentication (http_signature_test) required
|
||||
if (this.Configuration.HTTPSigningConfiguration != null)
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HTTPSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "PUT", "/pet", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
|
@ -96,9 +96,9 @@ namespace Org.OpenAPITools.Client
|
||||
private IList<IReadOnlyDictionary<string, object>> _servers;
|
||||
|
||||
/// <summary>
|
||||
/// HTTPSigning configuration
|
||||
/// HttpSigning configuration
|
||||
/// </summary>
|
||||
private HTTPSigningConfiguration _HTTPSigningConfiguration = null;
|
||||
private HttpSigningConfiguration _HttpSigningConfiguration = null;
|
||||
#endregion Private Members
|
||||
|
||||
#region Constructors
|
||||
@ -493,12 +493,12 @@ namespace Org.OpenAPITools.Client
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and Sets the HTTPSigningConfiuration
|
||||
/// Gets and Sets the HttpSigningConfiuration
|
||||
/// </summary>
|
||||
public HTTPSigningConfiguration HTTPSigningConfiguration
|
||||
public HttpSigningConfiguration HttpSigningConfiguration
|
||||
{
|
||||
get { return _HTTPSigningConfiguration; }
|
||||
set { _HTTPSigningConfiguration = value; }
|
||||
get { return _HttpSigningConfiguration; }
|
||||
set { _HttpSigningConfiguration = value; }
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
@ -572,7 +572,7 @@ namespace Org.OpenAPITools.Client
|
||||
Username = second.Username ?? first.Username,
|
||||
Password = second.Password ?? first.Password,
|
||||
AccessToken = second.AccessToken ?? first.AccessToken,
|
||||
HTTPSigningConfiguration = second.HTTPSigningConfiguration ?? first.HTTPSigningConfiguration,
|
||||
HttpSigningConfiguration = second.HttpSigningConfiguration ?? first.HttpSigningConfiguration,
|
||||
TempFolderPath = second.TempFolderPath ?? first.TempFolderPath,
|
||||
DateTimeFormat = second.DateTimeFormat ?? first.DateTimeFormat
|
||||
};
|
||||
|
@ -12,15 +12,15 @@ using System.Web;
|
||||
namespace Org.OpenAPITools.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for HTTPSigning auth related parameter and methods
|
||||
/// Class for HttpSigning auth related parameter and methods
|
||||
/// </summary>
|
||||
public class HTTPSigningConfiguration
|
||||
public class HttpSigningConfiguration
|
||||
{
|
||||
#region
|
||||
/// <summary>
|
||||
/// Initailize the HashAlgorithm and SigningAlgorithm to default value
|
||||
/// </summary>
|
||||
public HTTPSigningConfiguration()
|
||||
public HttpSigningConfiguration()
|
||||
{
|
||||
HashAlgorithm = HashAlgorithmName.SHA256;
|
||||
SigningAlgorithm = "PKCS1-v15";
|
||||
@ -46,7 +46,7 @@ namespace Org.OpenAPITools.Client
|
||||
/// <summary>
|
||||
/// Gets the HTTP signing header
|
||||
/// </summary>
|
||||
public List<string> HTTPSigningHeader { get; set; }
|
||||
public List<string> HttpSigningHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash algorithm sha256 or sha512
|
||||
@ -76,12 +76,11 @@ namespace Org.OpenAPITools.Client
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Gets the Headers for HTTpSIgning
|
||||
/// Gets the Headers for HttpSigning
|
||||
/// </summary>
|
||||
/// <param name="basePath">Base path</param>
|
||||
/// <param name="method">HTTP method</param>
|
||||
/// <param name="path">Path</param>
|
||||
/// <param name="requestOptions">Request options</param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="requestOptions"></param>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string method, string path, RequestOptions requestOptions)
|
||||
{
|
||||
@ -103,12 +102,12 @@ namespace Org.OpenAPITools.Client
|
||||
const string HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
//Hash table to store singed headers
|
||||
var httpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var httpSignatureHeader = new Dictionary<string, string>();
|
||||
var HttpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var HttpSignatureHeader = new Dictionary<string, string>();
|
||||
|
||||
if (HTTPSigningHeader.Count == 0)
|
||||
if (HttpSigningHeader.Count == 0)
|
||||
{
|
||||
HTTPSigningHeader.Add("(created)");
|
||||
HttpSigningHeader.Add("(created)");
|
||||
}
|
||||
|
||||
if (requestOptions.PathParameters != null)
|
||||
@ -167,37 +166,37 @@ namespace Org.OpenAPITools.Client
|
||||
}
|
||||
|
||||
|
||||
foreach (var header in HTTPSigningHeader)
|
||||
foreach (var header in HttpSigningHeader)
|
||||
{
|
||||
if (header.Equals(HEADER_REQUEST_TARGET))
|
||||
{
|
||||
var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
|
||||
httpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
HttpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
}
|
||||
else if (header.Equals(HEADER_EXPIRES))
|
||||
{
|
||||
var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
|
||||
httpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DATE))
|
||||
{
|
||||
var utcDateTime = dateTime.ToString("r").ToString();
|
||||
httpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
httpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
}
|
||||
else if (header.Equals(HEADER_HOST))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
httpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
}
|
||||
else if (header.Equals(HEADER_CREATED))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DIGEST))
|
||||
{
|
||||
httpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
httpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
HttpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -206,7 +205,7 @@ namespace Org.OpenAPITools.Client
|
||||
{
|
||||
if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
httpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
isHeaderFound = true;
|
||||
break;
|
||||
}
|
||||
@ -218,10 +217,10 @@ namespace Org.OpenAPITools.Client
|
||||
}
|
||||
|
||||
}
|
||||
var headersKeysString = String.Join(" ", httpSignatureHeader.Keys);
|
||||
var headersKeysString = String.Join(" ", HttpSignatureHeader.Keys);
|
||||
var headerValuesList = new List<string>();
|
||||
|
||||
foreach (var keyVal in httpSignatureHeader)
|
||||
foreach (var keyVal in HttpSignatureHeader)
|
||||
{
|
||||
headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
|
||||
|
||||
@ -245,22 +244,22 @@ namespace Org.OpenAPITools.Client
|
||||
KeyId, cryptographicScheme);
|
||||
|
||||
|
||||
if (httpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",created={0}", httpSignatureHeader[HEADER_CREATED]);
|
||||
authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
|
||||
}
|
||||
|
||||
if (httpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",expires={0}", httpSignatureHeader[HEADER_EXPIRES]);
|
||||
authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
|
||||
}
|
||||
|
||||
authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
|
||||
headersKeysString, headerSignatureStr);
|
||||
|
||||
httpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
|
||||
return httpSignedRequestHeader;
|
||||
return HttpSignedRequestHeader;
|
||||
}
|
||||
|
||||
private byte[] GetStringHash(string hashName, string stringToBeHashed)
|
||||
@ -314,16 +313,16 @@ namespace Org.OpenAPITools.Client
|
||||
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
|
||||
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
|
||||
var ecdsa = ECDsa.Create();
|
||||
var bytCount = 0;
|
||||
|
||||
#if (NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0)
|
||||
var byteCount = 0;
|
||||
if (configuration.KeyPassPhrase != null)
|
||||
{
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out byteCount);
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out bytCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out byteCount);
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out bytCount);
|
||||
}
|
||||
var signedBytes = ecdsa.SignHash(dataToSign);
|
||||
var derBytes = ConvertToECDSAANS1Format(signedBytes);
|
||||
@ -688,6 +687,7 @@ namespace Org.OpenAPITools.Client
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
|
||||
/*this type of key can hold many type different types of private key, but here due lack of pem header
|
||||
Considering this as EC key
|
||||
*/
|
||||
|
@ -0,0 +1,706 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace Org.OpenAPITools.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for HttpSigning auth related parameter and methods
|
||||
/// </summary>
|
||||
public class HttpSigningConfiguration
|
||||
{
|
||||
#region
|
||||
/// <summary>
|
||||
/// Initailize the HashAlgorithm and SigningAlgorithm to default value
|
||||
/// </summary>
|
||||
public HttpSigningConfiguration()
|
||||
{
|
||||
HashAlgorithm = HashAlgorithmName.SHA256;
|
||||
SigningAlgorithm = "PKCS1-v15";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
///Gets the Api keyId
|
||||
/// </summary>
|
||||
public string KeyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Key file path
|
||||
/// </summary>
|
||||
public string KeyFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key pass phrase for password protected key
|
||||
/// </summary>
|
||||
public SecureString KeyPassPhrase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP signing header
|
||||
/// </summary>
|
||||
public List<string> HttpSigningHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash algorithm sha256 or sha512
|
||||
/// </summary>
|
||||
public HashAlgorithmName HashAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the signing algorithm
|
||||
/// </summary>
|
||||
public string SigningAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Signature validaty period in seconds
|
||||
/// </summary>
|
||||
public int SignatureValidityPeriod { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region enum
|
||||
private enum PrivateKeyType
|
||||
{
|
||||
None = 0,
|
||||
RSA = 1,
|
||||
ECDSA = 2,
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Gets the Headers for HttpSigning
|
||||
/// </summary>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="requestOptions"></param>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string method, string path, RequestOptions requestOptions)
|
||||
{
|
||||
const string HEADER_REQUEST_TARGET = "(request-target)";
|
||||
//The time when the HTTP signature expires. The API server should reject HTTP requests
|
||||
//that have expired.
|
||||
const string HEADER_EXPIRES = "(expires)";
|
||||
//The 'Date' header.
|
||||
const string HEADER_DATE = "Date";
|
||||
//The 'Host' header.
|
||||
const string HEADER_HOST = "Host";
|
||||
//The time when the HTTP signature was generated.
|
||||
const string HEADER_CREATED = "(created)";
|
||||
//When the 'Digest' header is included in the HTTP signature, the client automatically
|
||||
//computes the digest of the HTTP request body, per RFC 3230.
|
||||
const string HEADER_DIGEST = "Digest";
|
||||
//The 'Authorization' header is automatically generated by the client. It includes
|
||||
//the list of signed headers and a base64-encoded signature.
|
||||
const string HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
//Hash table to store singed headers
|
||||
var HttpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var HttpSignatureHeader = new Dictionary<string, string>();
|
||||
|
||||
if (HttpSigningHeader.Count == 0)
|
||||
{
|
||||
HttpSigningHeader.Add("(created)");
|
||||
}
|
||||
|
||||
if (requestOptions.PathParameters != null)
|
||||
{
|
||||
foreach (var pathParam in requestOptions.PathParameters)
|
||||
{
|
||||
var tempPath = path.Replace(pathParam.Key, "0");
|
||||
path = string.Format(tempPath, pathParam.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var httpValues = HttpUtility.ParseQueryString(String.Empty);
|
||||
foreach (var parameter in requestOptions.QueryParameters)
|
||||
{
|
||||
if (parameter.Value.Count > 1)
|
||||
{ // array
|
||||
foreach (var value in parameter.Value)
|
||||
{
|
||||
httpValues.Add(parameter.Key + "[]", value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
httpValues.Add(parameter.Key, parameter.Value[0]);
|
||||
|
||||
}
|
||||
}
|
||||
var uriBuilder = new UriBuilder(string.Concat(basePath, path));
|
||||
uriBuilder.Query = httpValues.ToString();
|
||||
|
||||
var dateTime = DateTime.Now;
|
||||
String Digest = String.Empty;
|
||||
|
||||
//get the body
|
||||
string requestBody = string.Empty;
|
||||
if (requestOptions.Data != null)
|
||||
{
|
||||
var serializerSettings = new JsonSerializerSettings();
|
||||
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
requestBody = JsonConvert.SerializeObject(requestOptions.Data, serializerSettings);
|
||||
}
|
||||
|
||||
if (HashAlgorithm == HashAlgorithmName.SHA256)
|
||||
{
|
||||
var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
|
||||
Digest = string.Format("SHA-256={0}", Convert.ToBase64String(bodyDigest));
|
||||
}
|
||||
else if (HashAlgorithm == HashAlgorithmName.SHA512)
|
||||
{
|
||||
var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
|
||||
Digest = string.Format("SHA-512={0}", Convert.ToBase64String(bodyDigest));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(string.Format("{0} not supported", HashAlgorithm));
|
||||
}
|
||||
|
||||
|
||||
foreach (var header in HttpSigningHeader)
|
||||
{
|
||||
if (header.Equals(HEADER_REQUEST_TARGET))
|
||||
{
|
||||
var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
|
||||
HttpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
}
|
||||
else if (header.Equals(HEADER_EXPIRES))
|
||||
{
|
||||
var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DATE))
|
||||
{
|
||||
var utcDateTime = dateTime.ToString("r").ToString();
|
||||
HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
}
|
||||
else if (header.Equals(HEADER_HOST))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
}
|
||||
else if (header.Equals(HEADER_CREATED))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DIGEST))
|
||||
{
|
||||
HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
HttpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isHeaderFound = false;
|
||||
foreach (var item in requestOptions.HeaderParameters)
|
||||
{
|
||||
if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
isHeaderFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isHeaderFound)
|
||||
{
|
||||
throw new Exception(string.Format("Cannot sign HTTP request.Request does not contain the {0} header.",header));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
var headersKeysString = String.Join(" ", HttpSignatureHeader.Keys);
|
||||
var headerValuesList = new List<string>();
|
||||
|
||||
foreach (var keyVal in HttpSignatureHeader)
|
||||
{
|
||||
headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
|
||||
|
||||
}
|
||||
//Concatinate headers value separated by new line
|
||||
var headerValuesString = string.Join("\n", headerValuesList);
|
||||
var signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
|
||||
string headerSignatureStr = null;
|
||||
var keyType = GetKeyType(KeyFilePath);
|
||||
|
||||
if (keyType == PrivateKeyType.RSA)
|
||||
{
|
||||
headerSignatureStr = GetRSASignature(signatureStringHash);
|
||||
}
|
||||
else if (keyType == PrivateKeyType.ECDSA)
|
||||
{
|
||||
headerSignatureStr = GetECDSASignature(signatureStringHash);
|
||||
}
|
||||
var cryptographicScheme = "hs2019";
|
||||
var authorizationHeaderValue = string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\"",
|
||||
KeyId, cryptographicScheme);
|
||||
|
||||
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
|
||||
}
|
||||
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
|
||||
}
|
||||
|
||||
authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
|
||||
headersKeysString, headerSignatureStr);
|
||||
|
||||
HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
|
||||
return HttpSignedRequestHeader;
|
||||
}
|
||||
|
||||
private byte[] GetStringHash(string hashName, string stringToBeHashed)
|
||||
{
|
||||
var hashAlgorithm = System.Security.Cryptography.HashAlgorithm.Create(hashName);
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(stringToBeHashed);
|
||||
var stringHash = hashAlgorithm.ComputeHash(bytes);
|
||||
return stringHash;
|
||||
}
|
||||
|
||||
private int GetUnixTime(DateTime date2)
|
||||
{
|
||||
DateTime date1 = new DateTime(1970, 01, 01);
|
||||
TimeSpan timeSpan = date2 - date1;
|
||||
return (int)timeSpan.TotalSeconds;
|
||||
}
|
||||
|
||||
private string GetRSASignature(byte[] stringToSign)
|
||||
{
|
||||
RSA rsa = GetRSAProviderFromPemFile(KeyFilePath, KeyPassPhrase);
|
||||
if (SigningAlgorithm == "RSASSA-PSS")
|
||||
{
|
||||
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pss);
|
||||
return Convert.ToBase64String(signedbytes);
|
||||
|
||||
}
|
||||
else if (SigningAlgorithm == "PKCS1-v15")
|
||||
{
|
||||
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pkcs1);
|
||||
return Convert.ToBase64String(signedbytes);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ECDSA signature
|
||||
/// </summary>
|
||||
/// <param name="dataToSign"></param>
|
||||
/// <returns></returns>
|
||||
private string GetECDSASignature(byte[] dataToSign)
|
||||
{
|
||||
if (!File.Exists(KeyFilePath))
|
||||
{
|
||||
throw new Exception("key file path does not exist.");
|
||||
}
|
||||
|
||||
var ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----";
|
||||
var ecKeyFooter = "-----END EC PRIVATE KEY-----";
|
||||
var keyStr = File.ReadAllText(KeyFilePath);
|
||||
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
|
||||
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
|
||||
var ecdsa = ECDsa.Create();
|
||||
var bytCount = 0;
|
||||
|
||||
#if (NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0)
|
||||
if (configuration.KeyPassPhrase != null)
|
||||
{
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(keyPassPhrase, keyBytes, out bytCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out bytCount);
|
||||
}
|
||||
var signedBytes = ecdsa.SignHash(dataToSign);
|
||||
var derBytes = ConvertToECDSAANS1Format(signedBytes);
|
||||
var signedString = System.Convert.ToBase64String(derBytes);
|
||||
|
||||
return signedString;
|
||||
#else
|
||||
throw new Exception("ECDSA signing is supported only on NETCOREAPP3_0 and above");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private byte[] ConvertToECDSAANS1Format(byte[] signedBytes)
|
||||
{
|
||||
var derBytes = new List<byte>();
|
||||
byte derLength = 68; //default lenght for ECDSA code signinged bit 0x44
|
||||
byte rbytesLength = 32; //R length 0x20
|
||||
byte sbytesLength = 32; //S length 0x20
|
||||
var rBytes = new List<byte>();
|
||||
var sBytes = new List<byte>();
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
rBytes.Add(signedBytes[i]);
|
||||
}
|
||||
for (int i = 32; i < 64; i++)
|
||||
{
|
||||
sBytes.Add(signedBytes[i]);
|
||||
}
|
||||
|
||||
if (rBytes[0] > 0x7F)
|
||||
{
|
||||
derLength++;
|
||||
rbytesLength++;
|
||||
var tempBytes = new List<byte>();
|
||||
tempBytes.AddRange(rBytes);
|
||||
rBytes.Clear();
|
||||
rBytes.Add(0x00);
|
||||
rBytes.AddRange(tempBytes);
|
||||
}
|
||||
|
||||
if (sBytes[0] > 0x7F)
|
||||
{
|
||||
derLength++;
|
||||
sbytesLength++;
|
||||
var tempBytes = new List<byte>();
|
||||
tempBytes.AddRange(sBytes);
|
||||
sBytes.Clear();
|
||||
sBytes.Add(0x00);
|
||||
sBytes.AddRange(tempBytes);
|
||||
|
||||
}
|
||||
|
||||
derBytes.Add(48); //start of the sequence 0x30
|
||||
derBytes.Add(derLength); //total length r lenth, type and r bytes
|
||||
|
||||
derBytes.Add(2); //tag for integer
|
||||
derBytes.Add(rbytesLength); //length of r
|
||||
derBytes.AddRange(rBytes);
|
||||
|
||||
derBytes.Add(2); //tag for integer
|
||||
derBytes.Add(sbytesLength); //length of s
|
||||
derBytes.AddRange(sBytes);
|
||||
return derBytes.ToArray();
|
||||
}
|
||||
|
||||
private RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile, SecureString keyPassPharse = 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();
|
||||
|
||||
if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
|
||||
{
|
||||
isPrivateKeyFile = false;
|
||||
}
|
||||
|
||||
if (isPrivateKeyFile)
|
||||
{
|
||||
pemkey = ConvertPrivateKeyToBytes(pemstr, keyPassPharse);
|
||||
if (pemkey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return DecodeRSAPrivateKey(pemkey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private byte[] ConvertPrivateKeyToBytes(String instr, SecureString keyPassPharse = null)
|
||||
{
|
||||
const String pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
|
||||
const String pemprivfooter = "-----END RSA PRIVATE KEY-----";
|
||||
String pemstr = instr.Trim();
|
||||
byte[] binkey;
|
||||
|
||||
if (!pemstr.StartsWith(pemprivheader) || !pemstr.EndsWith(pemprivfooter))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(pemstr);
|
||||
sb.Replace(pemprivheader, "");
|
||||
sb.Replace(pemprivfooter, "");
|
||||
String pvkstr = sb.ToString().Trim();
|
||||
|
||||
try
|
||||
{ // if there are no PEM encryption info lines, this is an UNencrypted PEM private key
|
||||
binkey = Convert.FromBase64String(pvkstr);
|
||||
return binkey;
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{
|
||||
StringReader str = new StringReader(pvkstr);
|
||||
|
||||
//-------- read PEM encryption info. lines and extract salt -----
|
||||
if (!str.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED"))
|
||||
return null;
|
||||
String saltline = str.ReadLine();
|
||||
if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,"))
|
||||
return null;
|
||||
String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim();
|
||||
byte[] salt = new byte[saltstr.Length / 2];
|
||||
for (int i = 0; i < salt.Length; i++)
|
||||
salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16);
|
||||
if (!(str.ReadLine() == ""))
|
||||
return null;
|
||||
|
||||
//------ remaining b64 data is encrypted RSA key ----
|
||||
String encryptedstr = str.ReadToEnd();
|
||||
|
||||
try
|
||||
{ //should have b64 encrypted RSA key now
|
||||
binkey = Convert.FromBase64String(encryptedstr);
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{ //data is not in base64 fromat
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] deskey = GetEncryptedKey(salt, keyPassPharse, 1, 2); // count=1 (for OpenSSL implementation); 2 iterations to get at least 24 bytes
|
||||
if (deskey == null)
|
||||
return null;
|
||||
|
||||
//------ Decrypt the encrypted 3des-encrypted RSA private key ------
|
||||
byte[] rsakey = DecryptKey(binkey, deskey, salt); //OpenSSL uses salt value in PEM header also as 3DES IV
|
||||
return rsakey;
|
||||
}
|
||||
}
|
||||
|
||||
private RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
|
||||
{
|
||||
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
|
||||
|
||||
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
|
||||
MemoryStream mem = new MemoryStream(privkey);
|
||||
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
|
||||
byte bt = 0;
|
||||
ushort twobytes = 0;
|
||||
int elems = 0;
|
||||
try
|
||||
{
|
||||
twobytes = binr.ReadUInt16();
|
||||
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
|
||||
binr.ReadByte(); //advance 1 byte
|
||||
else if (twobytes == 0x8230)
|
||||
binr.ReadInt16(); //advance 2 bytes
|
||||
else
|
||||
return null;
|
||||
|
||||
twobytes = binr.ReadUInt16();
|
||||
if (twobytes != 0x0102) //version number
|
||||
return null;
|
||||
bt = binr.ReadByte();
|
||||
if (bt != 0x00)
|
||||
return null;
|
||||
|
||||
//------ all private key components are Integer sequences ----
|
||||
elems = GetIntegerSize(binr);
|
||||
MODULUS = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
E = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
D = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
P = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
Q = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
DP = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
DQ = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
IQ = binr.ReadBytes(elems);
|
||||
|
||||
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
RSAParameters RSAparams = new RSAParameters();
|
||||
RSAparams.Modulus = MODULUS;
|
||||
RSAparams.Exponent = E;
|
||||
RSAparams.D = D;
|
||||
RSAparams.P = P;
|
||||
RSAparams.Q = Q;
|
||||
RSAparams.DP = DP;
|
||||
RSAparams.DQ = DQ;
|
||||
RSAparams.InverseQ = IQ;
|
||||
RSA.ImportParameters(RSAparams);
|
||||
return RSA;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally { binr.Close(); }
|
||||
}
|
||||
|
||||
private int GetIntegerSize(BinaryReader binr)
|
||||
{
|
||||
byte bt = 0;
|
||||
byte lowbyte = 0x00;
|
||||
byte highbyte = 0x00;
|
||||
int count = 0;
|
||||
bt = binr.ReadByte();
|
||||
if (bt != 0x02) //expect integer
|
||||
return 0;
|
||||
bt = binr.ReadByte();
|
||||
|
||||
if (bt == 0x81)
|
||||
count = binr.ReadByte(); // data size in next byte
|
||||
else if (bt == 0x82)
|
||||
{
|
||||
highbyte = binr.ReadByte(); // data size in next 2 bytes
|
||||
lowbyte = binr.ReadByte();
|
||||
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
|
||||
count = BitConverter.ToInt32(modint, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = bt; // we already have the data size
|
||||
}
|
||||
while (binr.ReadByte() == 0x00)
|
||||
{ //remove high order zeros in data
|
||||
count -= 1;
|
||||
}
|
||||
binr.BaseStream.Seek(-1, SeekOrigin.Current);
|
||||
//last ReadByte wasn't a removed zero, so back up a byte
|
||||
return count;
|
||||
}
|
||||
|
||||
private byte[] GetEncryptedKey(byte[] salt, SecureString secpswd, int count, int miter)
|
||||
{
|
||||
IntPtr unmanagedPswd = IntPtr.Zero;
|
||||
int HASHLENGTH = 16; //MD5 bytes
|
||||
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store contatenated Mi hashed results
|
||||
|
||||
byte[] psbytes = new byte[secpswd.Length];
|
||||
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
|
||||
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
|
||||
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
|
||||
|
||||
// --- contatenate salt and pswd bytes into fixed data array ---
|
||||
byte[] data00 = new byte[psbytes.Length + salt.Length];
|
||||
Array.Copy(psbytes, data00, psbytes.Length); //copy the pswd bytes
|
||||
Array.Copy(salt, 0, data00, psbytes.Length, salt.Length); //concatenate the salt bytes
|
||||
|
||||
// ---- do multi-hashing and contatenate results D1, D2 ... into keymaterial bytes ----
|
||||
MD5 md5 = new MD5CryptoServiceProvider();
|
||||
byte[] result = null;
|
||||
byte[] hashtarget = new byte[HASHLENGTH + data00.Length]; //fixed length initial hashtarget
|
||||
|
||||
for (int j = 0; j < miter; j++)
|
||||
{
|
||||
// ---- Now hash consecutively for count times ------
|
||||
if (j == 0)
|
||||
result = data00; //initialize
|
||||
else
|
||||
{
|
||||
Array.Copy(result, hashtarget, result.Length);
|
||||
Array.Copy(data00, 0, hashtarget, result.Length, data00.Length);
|
||||
result = hashtarget;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
result = md5.ComputeHash(result);
|
||||
Array.Copy(result, 0, keymaterial, j * HASHLENGTH, result.Length); //contatenate to keymaterial
|
||||
}
|
||||
byte[] deskey = new byte[24];
|
||||
Array.Copy(keymaterial, deskey, deskey.Length);
|
||||
|
||||
Array.Clear(psbytes, 0, psbytes.Length);
|
||||
Array.Clear(data00, 0, data00.Length);
|
||||
Array.Clear(result, 0, result.Length);
|
||||
Array.Clear(hashtarget, 0, hashtarget.Length);
|
||||
Array.Clear(keymaterial, 0, keymaterial.Length);
|
||||
return deskey;
|
||||
}
|
||||
|
||||
private byte[] DecryptKey(byte[] cipherData, byte[] desKey, byte[] IV)
|
||||
{
|
||||
MemoryStream memst = new MemoryStream();
|
||||
TripleDES alg = TripleDES.Create();
|
||||
alg.Key = desKey;
|
||||
alg.IV = IV;
|
||||
try
|
||||
{
|
||||
CryptoStream cs = new CryptoStream(memst, alg.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(cipherData, 0, cipherData.Length);
|
||||
cs.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
byte[] decryptedData = memst.ToArray();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detect the key type from the pem file.
|
||||
/// </summary>
|
||||
/// <param name="keyFilePath">key file path in pem format</param>
|
||||
/// <returns></returns>
|
||||
private PrivateKeyType GetKeyType(string keyFilePath)
|
||||
{
|
||||
if (!File.Exists(keyFilePath))
|
||||
{
|
||||
throw new Exception("Key file path does not exist.");
|
||||
}
|
||||
|
||||
var ecPrivateKeyHeader = "BEGIN EC PRIVATE KEY";
|
||||
var ecPrivateKeyFooter = "END EC PRIVATE KEY";
|
||||
var rsaPrivateKeyHeader = "BEGIN RSA PRIVATE KEY";
|
||||
var rsaPrivateFooter = "END RSA PRIVATE KEY";
|
||||
var pkcs8Header = "BEGIN PRIVATE KEY";
|
||||
var pkcs8Footer = "END PRIVATE KEY";
|
||||
var keyType = PrivateKeyType.None;
|
||||
var key = File.ReadAllLines(keyFilePath);
|
||||
|
||||
if (key[0].ToString().Contains(rsaPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(rsaPrivateFooter))
|
||||
{
|
||||
keyType = PrivateKeyType.RSA;
|
||||
}
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
keyType = PrivateKeyType.ECDSA;
|
||||
}
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
|
||||
/*this type of key can hold many type different types of private key, but here due lack of pem header
|
||||
Considering this as EC key
|
||||
*/
|
||||
//TODO :- update the key based on oid
|
||||
keyType = PrivateKeyType.ECDSA;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Either the key is invalid or key is not supported");
|
||||
|
||||
}
|
||||
return keyType;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -106,8 +106,8 @@ namespace Org.OpenAPITools.Client
|
||||
X509CertificateCollection ClientCertificates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTPSigning configuration
|
||||
/// Gets the HttpSigning configuration
|
||||
/// </summary>
|
||||
HTTPSigningConfiguration HTTPSigningConfiguration { get; }
|
||||
HttpSigningConfiguration HttpSigningConfiguration { get; }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user