Add powershell echo test, rename api key names (#17043)

* add powershell echo test, rename api key names

* update
This commit is contained in:
William Cheng
2023-11-13 00:09:46 +08:00
committed by GitHub
parent 6917aad760
commit 372894dd1d
74 changed files with 6875 additions and 19 deletions

View File

@@ -0,0 +1,260 @@
#
# Echo Server API
# Echo Server API
# Version: 0.1.0
# Contact: team@openapitools.org
# Generated by OpenAPI Generator: https://openapi-generator.tech
#
function Invoke-ApiClient {
[OutputType('System.Collections.Hashtable')]
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[string]$Uri,
[Parameter(Mandatory)]
[AllowEmptyCollection()]
[string[]]$Accepts,
[Parameter(Mandatory)]
[AllowEmptyCollection()]
[string[]]$ContentTypes,
[Parameter(Mandatory)]
[hashtable]$HeaderParameters,
[Parameter(Mandatory)]
[hashtable]$FormParameters,
[Parameter(Mandatory)]
[hashtable]$QueryParameters,
[Parameter(Mandatory)]
[hashtable]$CookieParameters,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$Body,
[Parameter(Mandatory)]
[string]$Method,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$ReturnType,
[Parameter(Mandatory)]
[bool]$IsBodyNullable
)
'Calling method: Invoke-ApiClient' | Write-Debug
$PSBoundParameters | Out-DebugParameter | Write-Debug
$Configuration = Get-Configuration
$RequestUri = $Configuration["BaseUrl"] + $Uri
$SkipCertificateCheck = $Configuration["SkipCertificateCheck"]
# cookie parameters
foreach ($Parameter in $CookieParameters.GetEnumerator()) {
if ($Parameter.Name -eq "cookieAuth") {
$HeaderParameters["Cookie"] = $Parameter.Value
} else {
$HeaderParameters[$Parameter.Name] = $Parameter.Value
}
}
if ($CookieParameters -and $CookieParameters.Count -gt 1) {
Write-Warning "Multiple cookie parameters found. Currently only the first one is supported/used"
}
# accept, content-type headers
$Accept = SelectHeaders -Headers $Accepts
if ($Accept) {
$HeaderParameters['Accept'] = $Accept
}
[string]$MultiPartBoundary = $null
$ContentType= SelectHeaders -Headers $ContentTypes
if ($ContentType) {
$HeaderParameters['Content-Type'] = $ContentType
if ($ContentType -eq 'multipart/form-data') {
[string]$MultiPartBoundary = [System.Guid]::NewGuid()
$MultiPartBoundary = "---------------------------$MultiPartBoundary"
$HeaderParameters['Content-Type'] = "$ContentType; boundary=$MultiPartBoundary"
}
}
# add default headers if any
foreach ($header in $Configuration["DefaultHeaders"].GetEnumerator()) {
$HeaderParameters[$header.Name] = $header.Value
}
# construct URL query string
$HttpValues = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
foreach ($Parameter in $QueryParameters.GetEnumerator()) {
if ($Parameter.Value.Count -gt 1) { // array
foreach ($Value in $Parameter.Value) {
$HttpValues.Add($Parameter.Key + '[]', $Value)
}
} else {
$HttpValues.Add($Parameter.Key,$Parameter.Value)
}
}
# Build the request and load it with the query string.
$UriBuilder = [System.UriBuilder]($RequestUri)
$UriBuilder.Query = $HttpValues.ToString()
# include form parameters in the request body
if ($FormParameters -and $FormParameters.Count -gt 0) {
if (![string]::IsNullOrEmpty($MultiPartBoundary)) {
$RequestBody = ""
$LF = "`r`n"
$FormParameters.Keys | ForEach-Object {
$value = $FormParameters[$_]
$isFile = $value.GetType().FullName -eq "System.IO.FileInfo"
$RequestBody += "--$MultiPartBoundary$LF"
$RequestBody += "Content-Disposition: form-data; name=`"$_`""
if ($isFile) {
$fileName = $value.Name
$RequestBody += "; filename=`"$fileName`"$LF"
$RequestBody += "Content-Type: application/octet-stream$LF$LF"
$RequestBody += Get-Content -Path $value.FullName
} else {
$RequestBody += "$LF$LF"
$RequestBody += ([string]$value)
}
$RequestBody += "$LF--$MultiPartBoundary"
}
$RequestBody += "--"
} else {
$RequestBody = $FormParameters
}
}
if ($Body -or $IsBodyNullable) {
$RequestBody = $Body
if ([string]::IsNullOrEmpty($RequestBody) -and $IsBodyNullable -eq $true) {
$RequestBody = "null"
}
}
if ($SkipCertificateCheck -eq $true) {
if ($null -eq $Configuration["Proxy"]) {
# skip certification check, no proxy
$Response = Invoke-WebRequest -Uri $UriBuilder.Uri `
-Method $Method `
-Headers $HeaderParameters `
-Body $RequestBody `
-ErrorAction Stop `
-UseBasicParsing `
-SkipCertificateCheck
} else {
# skip certification check, use proxy
$Response = Invoke-WebRequest -Uri $UriBuilder.Uri `
-Method $Method `
-Headers $HeaderParameters `
-Body $RequestBody `
-ErrorAction Stop `
-UseBasicParsing `
-SkipCertificateCheck `
-Proxy $Configuration["Proxy"].GetProxy($UriBuilder.Uri) `
-ProxyUseDefaultCredentials
}
} else {
if ($null -eq $Configuration["Proxy"]) {
# perform certification check, no proxy
$Response = Invoke-WebRequest -Uri $UriBuilder.Uri `
-Method $Method `
-Headers $HeaderParameters `
-Body $RequestBody `
-ErrorAction Stop `
-UseBasicParsing
} else {
# perform certification check, use proxy
$Response = Invoke-WebRequest -Uri $UriBuilder.Uri `
-Method $Method `
-Headers $HeaderParameters `
-Body $RequestBody `
-ErrorAction Stop `
-UseBasicParsing `
-Proxy $Configuration["Proxy"].GetProxy($UriBuilder.Uri) `
-ProxyUseDefaultCredentials
}
}
return @{
Response = DeserializeResponse -Response $Response -ReturnType $ReturnType -ContentTypes $Response.Headers["Content-Type"]
StatusCode = $Response.StatusCode
Headers = $Response.Headers
}
}
# Select JSON MIME if present, otherwise choose the first one if available
function SelectHeaders {
Param(
[Parameter(Mandatory)]
[AllowEmptyCollection()]
[String[]]$Headers
)
foreach ($Header in $Headers) {
if (IsJsonMIME -MIME $Header) {
return $Header
}
}
if (!($Headers) -or $Headers.Count -eq 0) {
return $null
} else {
return $Headers[0] # return the first one
}
}
function IsJsonMIME {
Param(
[Parameter(Mandatory)]
[string]$MIME
)
if ($MIME -match "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$") {
return $true
} else {
return $false
}
}
function DeserializeResponse {
Param(
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$ReturnType,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$Response,
[Parameter(Mandatory)]
[AllowEmptyCollection()]
[string[]]$ContentTypes
)
If ($null -eq $ContentTypes) {
$ContentTypes = [string[]]@()
}
If ([string]::IsNullOrEmpty($ReturnType) -and $ContentTypes.Count -eq 0) { # void response
return $Response
} Elseif ($ReturnType -match '\[\]$') { # array
return ConvertFrom-Json $Response
} Elseif (@("String", "Boolean", "System.DateTime") -contains $ReturnType) { # string, boolean ,datetime
return $Response
} Else { # others (e.g. model, file)
if ($ContentTypes) {
$ContentType = $null
if ($ContentTypes.Count -gt 1) {
$ContentType = SelectHeaders -Headers $ContentTypes
} else {
$ContentType = $ContentTypes[0]
}
if (IsJsonMIME -MIME $ContentType) { # JSON
return ConvertFrom-Json $Response
} else { # XML, file, etc
return $Response
}
} else { # no content type in response header, returning raw response
return $Response
}
}
}

View File

@@ -0,0 +1,22 @@
#
# Echo Server API
# Echo Server API
# Version: 0.1.0
# Contact: team@openapitools.org
# Generated by OpenAPI Generator: https://openapi-generator.tech
#
<#
.Synopsis
Helper function to get common parameters (Verbose, Debug, etc.)
.Example
Get-CommonParameters
#>
function Get-CommonParameters {
function tmp {
[CmdletBinding()]
Param ()
}
(Get-Command -Name tmp -CommandType Function).Parameters.Keys
}

View File

@@ -0,0 +1,437 @@
#
# Echo Server API
# Echo Server API
# Version: 0.1.0
# Contact: team@openapitools.org
# Generated by OpenAPI Generator: https://openapi-generator.tech
#
<#
.SYNOPSIS
Gets the headers for HTTP signature.
.DESCRIPTION
Gets the headers for the http signature.
.PARAMETER Method
HTTP method
.PARAMETER UriBuilder
UriBuilder for url and query parameter
.PARAMETER Body
Request body
.OUTPUTS
Hashtable
#>
function Get-HttpSignedHeader {
param(
[string]$Method,
[System.UriBuilder]$UriBuilder,
[string]$Body,
[hashtable]$RequestHeader
)
$HEADER_REQUEST_TARGET = '(request-target)'
# The time when the HTTP signature was generated.
$HEADER_CREATED = '(created)'
# The time when the HTTP signature expires. The API server should reject HTTP requests
# that have expired.
$HEADER_EXPIRES = '(expires)'
# The 'Host' header.
$HEADER_HOST = 'Host'
# The 'Date' header.
$HEADER_DATE = 'Date'
# When the 'Digest' header is included in the HTTP signature, the client automatically
# computes the digest of the HTTP request body, per RFC 3230.
$HEADER_DIGEST = 'Digest'
# The 'Authorization' header is automatically generated by the client. It includes
# the list of signed headers and a base64-encoded signature.
$HEADER_AUTHORIZATION = 'Authorization'
#Hash table to store singed headers
$HttpSignedRequestHeader = @{ }
$HttpSignatureHeader = @{ }
$TargetHost = $UriBuilder.Host
$httpSigningConfiguration = Get-ConfigurationHttpSigning
$Digest = $null
#get the body digest
$bodyHash = Get-StringHash -String $Body -HashName $httpSigningConfiguration.HashAlgorithm
if ($httpSigningConfiguration.HashAlgorithm -eq "SHA256") {
$Digest = [String]::Format("SHA-256={0}", [Convert]::ToBase64String($bodyHash))
} elseif ($httpSigningConfiguration.HashAlgorithm -eq "SHA512") {
$Digest = [String]::Format("SHA-512={0}", [Convert]::ToBase64String($bodyHash))
}
$dateTime = Get-Date
#get the date in UTC
$currentDate = $dateTime.ToUniversalTime().ToString("r")
foreach ($headerItem in $httpSigningConfiguration.HttpSigningHeader) {
if ($headerItem -eq $HEADER_REQUEST_TARGET) {
$requestTargetPath = [string]::Format("{0} {1}{2}", $Method.ToLower(), $UriBuilder.Path, $UriBuilder.Query)
$HttpSignatureHeader.Add($HEADER_REQUEST_TARGET, $requestTargetPath)
} elseif ($headerItem -eq $HEADER_CREATED) {
$created = Get-UnixTime -Date $dateTime -TotalTime TotalSeconds
$HttpSignatureHeader.Add($HEADER_CREATED, $created)
} elseif ($headerItem -eq $HEADER_EXPIRES) {
$expire = $dateTime.AddSeconds($httpSigningConfiguration.SignatureValidityPeriod)
$expireEpocTime = Get-UnixTime -Date $expire -TotalTime TotalSeconds
$HttpSignatureHeader.Add($HEADER_EXPIRES, $expireEpocTime)
} elseif ($headerItem -eq $HEADER_HOST) {
$HttpSignedRequestHeader[$HEADER_HOST] = $TargetHost
$HttpSignatureHeader.Add($HEADER_HOST.ToLower(), $TargetHost)
} elseif ($headerItem -eq $HEADER_DATE) {
$HttpSignedRequestHeader[$HEADER_DATE] = $currentDate
$HttpSignatureHeader.Add($HEADER_DATE.ToLower(), $currentDate)
} elseif ($headerItem -eq $HEADER_DIGEST) {
$HttpSignedRequestHeader[$HEADER_DIGEST] = $Digest
$HttpSignatureHeader.Add($HEADER_DIGEST.ToLower(), $Digest)
} elseif($RequestHeader.ContainsKey($headerItem)) {
$HttpSignatureHeader.Add($headerItem.ToLower(), $RequestHeader[$headerItem])
} else {
throw "Cannot sign HTTP request. Request does not contain the $headerItem header."
}
}
# header's name separated by space
$headersKeysString = $HttpSignatureHeader.Keys -join " "
$headerValuesList = @()
foreach ($item in $HttpSignatureHeader.GetEnumerator()) {
$headerValuesList += [string]::Format("{0}: {1}", $item.Name, $item.Value)
}
#Concatenate headers value separated by new line
$headerValuesString = $headerValuesList -join "`n"
#Gets the hash of the headers value
$signatureHashString = Get-StringHash -String $headerValuesString -HashName $httpSigningConfiguration.HashAlgorithm
#Gets the Key type to select the correct signing algorithm
$KeyType = Get-KeyTypeFromFile -KeyFilePath $httpSigningConfiguration.KeyFilePath
if ($keyType -eq "RSA") {
$headerSignatureStr = Get-RSASignature -PrivateKeyFilePath $httpSigningConfiguration.KeyFilePath `
-DataToSign $signatureHashString `
-HashAlgorithmName $httpSigningConfiguration.HashAlgorithm `
-KeyPassPhrase $httpSigningConfiguration.KeyPassPhrase `
-SigningAlgorithm $httpSigningConfiguration.SigningAlgorithm
} elseif ($KeyType -eq "EC") {
$headerSignatureStr = Get-ECDSASignature -ECKeyFilePath $httpSigningConfiguration.KeyFilePath `
-DataToSign $signatureHashString `
-HashAlgorithmName $httpSigningConfiguration.HashAlgorithm `
-KeyPassPhrase $httpSigningConfiguration.KeyPassPhrase
}
#Deprecated
<#$cryptographicScheme = Get-CryptographicScheme -SigningAlgorithm $httpSigningConfiguration.SigningAlgorithm `
-HashAlgorithm $httpSigningConfiguration.HashAlgorithm
#>
$cryptographicScheme = "hs2019"
$authorizationHeaderValue = [string]::Format("Signature keyId=""{0}"",algorithm=""{1}""",
$httpSigningConfiguration.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[$HEADER_AUTHORIZATION] = $authorizationHeaderValue
return $HttpSignedRequestHeader
}
<#
.SYNOPSIS
Gets the RSA signature
.DESCRIPTION
Gets the RSA signature for the http signing
.PARAMETER PrivateKeyFilePath
Specify the API key file path
.PARAMETER DataToSign
Specify the data to sign
.PARAMETER HashAlgorithmName
HashAlgorithm to calculate the hash
.PARAMETER KeyPassPhrase
KeyPassPhrase for the encrypted key
.OUTPUTS
Base64String
#>
function Get-RSASignature {
Param(
[string]$PrivateKeyFilePath,
[byte[]]$DataToSign,
[string]$HashAlgorithmName,
[string]$SigningAlgorithm,
[securestring]$KeyPassPhrase
)
try {
if ($hashAlgorithmName -eq "sha256") {
$hashAlgo = [System.Security.Cryptography.HashAlgorithmName]::SHA256
} elseif ($hashAlgorithmName -eq "sha512") {
$hashAlgo = [System.Security.Cryptography.HashAlgorithmName]::SHA512
}
if ($PSVersionTable.PSVersion.Major -ge 7) {
$ecKeyHeader = "-----BEGIN RSA PRIVATE KEY-----"
$ecKeyFooter = "-----END RSA PRIVATE KEY-----"
$keyStr = Get-Content -Path $PrivateKeyFilePath -Raw
$ecKeyBase64String = $keyStr.Replace($ecKeyHeader, "").Replace($ecKeyFooter, "").Trim()
$keyBytes = [System.Convert]::FromBase64String($ecKeyBase64String)
$rsa = [System.Security.Cryptography.RSA]::Create()
[int]$bytCount = 0
$rsa.ImportRSAPrivateKey($keyBytes, [ref] $bytCount)
if ($SigningAlgorithm -eq "RSASSA-PSS") {
$signedBytes = $rsa.SignHash($DataToSign, $hashAlgo, [System.Security.Cryptography.RSASignaturePadding]::Pss)
} else {
$signedBytes = $rsa.SignHash($DataToSign, $hashAlgo, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
}
} else {
$rsa_provider_path = Join-Path -Path $PSScriptRoot -ChildPath "RSAEncryptionProvider.cs"
$rsa_provider_sourceCode = Get-Content -Path $rsa_provider_path -Raw
Add-Type -TypeDefinition $rsa_provider_sourceCode
[System.Security.Cryptography.RSA]$rsa = [RSAEncryption.RSAEncryptionProvider]::GetRSAProviderFromPemFile($PrivateKeyFilePath, $KeyPassPhrase)
if ($SigningAlgorithm -eq "RSASSA-PSS") {
throw "$SigningAlgorithm is not supported on $($PSVersionTable.PSVersion)"
} else {
$signedBytes = $rsa.SignHash($DataToSign, $hashAlgo, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
}
}
$signedString = [Convert]::ToBase64String($signedBytes)
return $signedString
} catch {
throw $_
}
}
<#
.SYNOPSIS
Gets the ECDSA signature
.DESCRIPTION
Gets the ECDSA signature for the http signing
.PARAMETER PrivateKeyFilePath
Specify the API key file path
.PARAMETER DataToSign
Specify the data to sign
.PARAMETER HashAlgorithmName
HashAlgorithm to calculate the hash
.PARAMETER KeyPassPhrase
KeyPassPhrase for the encrypted key
.OUTPUTS
Base64String
#>
function Get-ECDSASignature {
param(
[Parameter(Mandatory = $true)]
[string]$ECKeyFilePath,
[Parameter(Mandatory = $true)]
[byte[]]$DataToSign,
[Parameter(Mandatory = $false)]
[String]$HashAlgorithmName,
[Parameter(Mandatory = $false)]
[securestring]$KeyPassPhrase
)
if (!(Test-Path -Path $ECKeyFilePath)) {
throw "key file path does not exist."
}
if ($PSVersionTable.PSVersion.Major -lt 7) {
throw "ECDSA key is not supported on PowerShell version $($PSVersionTable.PSVersion), Use PowerShell v7.0 and above"
}
$ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----"
$ecKeyFooter = "-----END EC PRIVATE KEY-----"
$keyStr = Get-Content -Path $ECKeyFilePath -Raw
$ecKeyBase64String = $keyStr.Replace($ecKeyHeader, "").Replace($ecKeyFooter, "").Trim()
$keyBytes = [System.Convert]::FromBase64String($ecKeyBase64String)
$ecdsa = [System.Security.Cryptography.ECDsa]::Create()
[int]$bytCount =0
if (![string]::IsNullOrEmpty($KeyPassPhrase)) {
$ecdsa.ImportEncryptedPkcs8PrivateKey($KeyPassPhrase,$keyBytes,[ref]$bytCount)
} else {
$ecdsa.ImportPkcs8PrivateKey($keyBytes,[ref]$bytCount)
}
$signedBytes = $ecdsa.SignHash($DataToSign)
$derBytes = ConvertTo-ECDSAANS1Format -RawBytes $signedBytes
$signedString = [System.Convert]::ToBase64String($derBytes)
return $signedString
}
<#
.Synopsis
Gets the hash of string.
.Description
Gets the hash of string
.Parameter String
Specifies the string to calculate the hash
.Parameter HashName
Specifies the hash name to calculate the hash, Accepted values are "SHA1", "SHA256" and "SHA512"
It is recommended not to use "SHA1" to calculate the Hash
.Outputs
String
#>
Function Get-StringHash {
param(
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[string]$String,
[Parameter(Mandatory = $true)]
[ValidateSet("SHA1", "SHA256", "SHA512")]
$HashName
)
$hashAlgorithm = [System.Security.Cryptography.HashAlgorithm]::Create($HashName)
$hashAlgorithm.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))
}
<#
.Synopsis
Gets the Unix time.
.Description
Gets the Unix time
.Parameter Date
Specifies the date to calculate the unix time
.Parameter ToTalTime
Specifies the total time , Accepted values are "TotalDays", "TotalHours", "TotalMinutes", "TotalSeconds" and "TotalMilliseconds"
.Outputs
Integer
#>
function Get-UnixTime {
param(
[Parameter(Mandatory = $true)]
[DateTime]$Date,
[Parameter(Mandatory = $false)]
[ValidateSet("TotalDays", "TotalHours", "TotalMinutes", "TotalSeconds", "TotalMilliseconds")]
[string]$TotalTime = "TotalSeconds"
)
$date1 = Get-Date -Date "01/01/1970"
$timespan = New-TimeSpan -Start $date1 -End $Date
switch ($TotalTime) {
"TotalDays" { [int]$timespan.TotalDays }
"TotalHours" { [int]$timespan.TotalHours }
"TotalMinutes" { [int]$timespan.TotalMinutes }
"TotalSeconds" { [int]$timespan.TotalSeconds }
"TotalMilliseconds" { [int]$timespan.TotalMilliseconds }
}
}
function Get-CryptographicScheme {
param(
[Parameter(Mandatory = $true)]
[string]$SigningAlgorithm,
[Parameter(Mandatory = $true)]
[string]$HashAlgorithm
)
$rsaSignatureType = @("RSASSA-PKCS1-v1_5", "RSASSA-PSS")
$SigningAlgorithm = $null
if ($rsaSignatureType -contains $SigningAlgorithm) {
switch ($HashAlgorithm) {
"sha256" { $SigningAlgorithm = "rsa-sha256" }
"sha512" { $SigningAlgorithm = "rsa-sha512" }
}
}
return $SigningAlgorithm
}
<#
.Synopsis
Gets the key type from the pem file.
.Description
Gets the key type from the pem file.
.Parameter KeyFilePath
Specifies the key file path (pem file)
.Outputs
String
#>
function Get-KeyTypeFromFile {
param(
[Parameter(Mandatory = $true)]
[string]$KeyFilePath
)
if (-not(Test-Path -Path $KeyFilePath)) {
throw "Key file path does not exist."
}
$ecPrivateKeyHeader = "BEGIN EC PRIVATE KEY"
$ecPrivateKeyFooter = "END EC PRIVATE KEY"
$rsaPrivateKeyHeader = "BEGIN RSA PRIVATE KEY"
$rsaPrivateFooter = "END RSA PRIVATE KEY"
$pkcs8Header = "BEGIN PRIVATE KEY"
$pkcs8Footer = "END PRIVATE KEY"
$keyType = $null
$key = Get-Content -Path $KeyFilePath
if ($key[0] -match $rsaPrivateKeyHeader -and $key[$key.Length - 1] -match $rsaPrivateFooter) {
$KeyType = "RSA"
} elseif ($key[0] -match $ecPrivateKeyHeader -and $key[$key.Length - 1] -match $ecPrivateKeyFooter) {
$keyType = "EC"
} elseif ($key[0] -match $ecPrivateKeyHeader -and $key[$key.Length - 1] -match $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 = "EC"
} else {
throw "Either the key is invalid or key is not supported"
}
return $keyType
}
<#
.Synopsis
Converts sequence of R and S bytes to ANS1 format for ECDSASignature.
.Description
Converts sequence of R and S bytes to ANS1 format for ECDSASignature.
.Parameter RawBytes[]
Specifies the R and S bytes of ECDSA signature.
.Outputs
Byte[]
#>
function ConvertTo-ECDSAANS1Format{
Param(
[Parameter(Mandatory = $true)]
[byte[]]$RawBytes
)
$derLength = 68 #default length for ECDSA code signing bit 0x44
$rbytesLength = 32 #R length 0x20
$sbytesLength = 32 #S length 0x20
[byte[]]$rBytes = $signedBytes[0..31]
[byte[]]$sBytes = $signedBytes[32..63]
if($rBytes[0] -gt 0x7F){
$derLength++
$rbytesLength++
$rBytes = [byte[]]@(0x00) + $rBytes
}
if($sBytes[0] -gt 0x7F){
$derLength++
$sbytesLength++
$sBytes = [byte[]]@(0x00) + $sBytes
}
[byte[]]$derBytes = @()
$derBytes += 48 # start of the sequence 0x30
$derBytes += $derLength # total length r length, type and r bytes
$derBytes += 2 # tag for integer
$derBytes += $rbytesLength # length of r
$derBytes += $rBytes
$derBytes += 2 #tag for integer
$derBytes += $sbytesLength #length of s
$derBytes += $sBytes
return $derBytes
}

View File

@@ -0,0 +1,45 @@
#
# Echo Server API
# Echo Server API
# Version: 0.1.0
# Contact: team@openapitools.org
# Generated by OpenAPI Generator: https://openapi-generator.tech
#
<#
.Synopsis
Helper function to format debug parameter output.
.Example
$PSBoundParameters | Out-DebugParameter | Write-Debug
#>
function Out-DebugParameter {
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline = $true, Mandatory = $true)]
[AllowEmptyCollection()]
$InputObject
)
Begin {
$CommonParameters = Get-CommonParameters
}
Process {
$InputObject.GetEnumerator() | Where-Object {
$CommonParameters -notcontains $_.Key
} | Format-Table -AutoSize -Property (
@{
Name = 'Parameter'
Expression = {$_.Key}
},
@{
Name = 'Value'
Expression = {$_.Value}
}
) | Out-String -Stream | ForEach-Object {
if ($_.Trim()) {
$_
}
}
}
}

View File

@@ -0,0 +1,354 @@
/*
* Echo Server API
*
* Echo Server API
*
* The version of the OpenAPI document: 0.1.0
* Contact: team@openapitools.org
* Generated by: https://github.com/openapitools/openapi-generator.git
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
namespace RSAEncryption
{
/// <summary>
/// A RSA enccryption provider.
/// </summary>
public class RSAEncryptionProvider
{
/// <summary>
/// Get the RSA provider from the PEM file.
/// </summary>
/// <param name="pemfile">PEM file.</param>
/// <param name="keyPassPhrase">Key pass phrase.</param>
/// <returns>Get an instance of RSACryptoServiceProvider.</returns>
public static RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile,SecureString keyPassPhrase = null)
{
const String pempubheader = "-----BEGIN PUBLIC KEY-----";
const String pempubfooter = "-----END PUBLIC KEY-----";
bool isPrivateKeyFile = true;
byte[] pemkey = null;
if (!File.Exists(pemfile))
{
throw new Exception("private key file does not exist.");
}
string pemstr = File.ReadAllText(pemfile).Trim();
if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
{
isPrivateKeyFile = false;
}
if (isPrivateKeyFile)
{
pemkey = ConvertPrivateKeyToBytes(pemstr,keyPassPhrase);
if (pemkey == null)
{
return null;
}
return DecodeRSAPrivateKey(pemkey);
}
return null ;
}
/// <summary>
/// Convert the private key to bytes.
/// </summary>
/// <param name="instr">Private key.</param>
/// <param name="keyPassPhrase">Key pass phrase.</param>
/// <returns>The private key in the form of bytes.</returns>
static byte[] ConvertPrivateKeyToBytes(String instr, SecureString keyPassPhrase = 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 format
return null;
}
byte[] deskey = GetEncryptedKey(salt, keyPassPhrase, 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;
}
}
/// <summary>
/// Decode the RSA private key.
/// </summary>
/// <param name="privkey">Private key.</param>
/// <returns>An instance of RSACryptoServiceProvider.</returns>
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] bytesModules, bytesE, bytesD, bytesP, bytesQ, bytesDp, bytesDq, bytesIq;
// --------- 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);
bytesModules = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesE = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesD = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesDp = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesDq = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesIq = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = bytesModules;
RSAparams.Exponent = bytesE;
RSAparams.D = bytesD;
RSAparams.P = bytesP;
RSAparams.Q = bytesQ;
RSAparams.DP = bytesDp;
RSAparams.DQ = bytesDq;
RSAparams.InverseQ = bytesIq;
rsa.ImportParameters(RSAparams);
return rsa;
}
catch (Exception)
{
return null;
}
finally
{
binr.Close();
}
}
private static 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;
}
/// <summary>
/// Get the encrypted key.
/// </summary>
/// <param name="salt">Random bytes to be added.</param>
/// <param name="secpswd">Password.</param>
/// <param name="count">Count.</param>
/// <param name="miter">Miter.</param>
/// <returns>Decrypted key.</returns>
static byte[] GetEncryptedKey(byte[] salt, SecureString secpswd, int count, int miter)
{
IntPtr unmanagedPswd = IntPtr.Zero;
const int HASHLENGTH = 16; //MD5 bytes
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store concatenated Mi hashed results
byte[] psbytes = new byte[secpswd.Length];
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
// --- concatenate 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 concatenate 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); //concatenate 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;
}
/// <summary>
/// Decrypt the key.
/// </summary>
/// <param name="chipherData">Cipher data.</param>
/// <param name="desKey">Key to decrypt.</param>
/// <param name="IV">Initialization vector.</param>
/// <returns>Decrypted key.</returns>
static 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;
}
}
}