diff --git a/modules/openapi-generator/src/main/resources/powershell/http_signature_auth.mustache b/modules/openapi-generator/src/main/resources/powershell/http_signature_auth.mustache index 698f9b248f4c..e1ae5f7aeed2 100644 --- a/modules/openapi-generator/src/main/resources/powershell/http_signature_auth.mustache +++ b/modules/openapi-generator/src/main/resources/powershell/http_signature_auth.mustache @@ -237,7 +237,7 @@ function Get-{{{apiNamePrefix}}}ECDSASignature { } if ($PSVersionTable.PSVersion.Major -lt 7) { - throw "ECDSA key is not supported on $($PSVersionTable.PSVersion), Use PSVersion 7.0 and above" + throw "ECDSA key is not supported on PowerShell version $($PSVersionTable.PSVersion), Use PowerShell v7.0 and above" } $ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----" @@ -245,10 +245,8 @@ function Get-{{{apiNamePrefix}}}ECDSASignature { $keyStr = Get-Content -Path $ECKeyFilePath -Raw $ecKeyBase64String = $keyStr.Replace($ecKeyHeader, "").Replace($ecKeyFooter, "").Trim() $keyBytes = [System.Convert]::FromBase64String($ecKeyBase64String) + $ecdsa = [System.Security.Cryptography.ECDsa]::Create() - #$cngKey = [System.Security.Cryptography.CngKey]::Import($keyBytes,[System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob) - #$ecdsa = [System.Security.Cryptography.ECDsaCng]::New($cngKey) - $ecdsa = [System.Security.Cryptography.ECDsaCng]::New() [int]$bytCount =0 if (![string]::IsNullOrEmpty($KeyPassPhrase)) { $ecdsa.ImportEncryptedPkcs8PrivateKey($KeyPassPhrase,$keyBytes,[ref]$bytCount) @@ -256,14 +254,9 @@ function Get-{{{apiNamePrefix}}}ECDSASignature { $ecdsa.ImportPkcs8PrivateKey($keyBytes,[ref]$bytCount) } - if ($HashAlgorithmName -eq "sha512") { - $ecdsa.HashAlgorithm = [System.Security.Cryptography.CngAlgorithm]::Sha512 - } else { - $ecdsa.HashAlgorithm = [System.Security.Cryptography.CngAlgorithm]::Sha256 - } - $signedBytes = $ecdsa.SignHash($DataToSign) - $signedString = [System.Convert]::ToBase64String($signedBytes) + $derBytes = ConvertTo-ECDSAANS1Format -RawBytes $signedBytes + $signedString = [System.Convert]::ToBase64String($derBytes) return $signedString } @@ -385,3 +378,53 @@ function Get-{{{apiNamePrefix}}}KeyTypeFromFile { } 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 lenght for ECDSA code signinged 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 lenth, 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 +} \ No newline at end of file diff --git a/samples/client/petstore/powershell/src/PSPetstore/Private/PSHttpSignatureAuth.ps1 b/samples/client/petstore/powershell/src/PSPetstore/Private/PSHttpSignatureAuth.ps1 index e3333ae336f4..43c6ad42fb32 100644 --- a/samples/client/petstore/powershell/src/PSPetstore/Private/PSHttpSignatureAuth.ps1 +++ b/samples/client/petstore/powershell/src/PSPetstore/Private/PSHttpSignatureAuth.ps1 @@ -243,7 +243,7 @@ function Get-PSECDSASignature { } if ($PSVersionTable.PSVersion.Major -lt 7) { - throw "ECDSA key is not supported on $($PSVersionTable.PSVersion), Use PSVersion 7.0 and above" + throw "ECDSA key is not supported on PowerShell version $($PSVersionTable.PSVersion), Use PowerShell v7.0 and above" } $ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----" @@ -251,10 +251,8 @@ function Get-PSECDSASignature { $keyStr = Get-Content -Path $ECKeyFilePath -Raw $ecKeyBase64String = $keyStr.Replace($ecKeyHeader, "").Replace($ecKeyFooter, "").Trim() $keyBytes = [System.Convert]::FromBase64String($ecKeyBase64String) + $ecdsa = [System.Security.Cryptography.ECDsa]::Create() - #$cngKey = [System.Security.Cryptography.CngKey]::Import($keyBytes,[System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob) - #$ecdsa = [System.Security.Cryptography.ECDsaCng]::New($cngKey) - $ecdsa = [System.Security.Cryptography.ECDsaCng]::New() [int]$bytCount =0 if (![string]::IsNullOrEmpty($KeyPassPhrase)) { $ecdsa.ImportEncryptedPkcs8PrivateKey($KeyPassPhrase,$keyBytes,[ref]$bytCount) @@ -262,14 +260,9 @@ function Get-PSECDSASignature { $ecdsa.ImportPkcs8PrivateKey($keyBytes,[ref]$bytCount) } - if ($HashAlgorithmName -eq "sha512") { - $ecdsa.HashAlgorithm = [System.Security.Cryptography.CngAlgorithm]::Sha512 - } else { - $ecdsa.HashAlgorithm = [System.Security.Cryptography.CngAlgorithm]::Sha256 - } - $signedBytes = $ecdsa.SignHash($DataToSign) - $signedString = [System.Convert]::ToBase64String($signedBytes) + $derBytes = ConvertTo-ECDSAANS1Format -RawBytes $signedBytes + $signedString = [System.Convert]::ToBase64String($derBytes) return $signedString } @@ -391,3 +384,53 @@ function Get-PSKeyTypeFromFile { } 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 lenght for ECDSA code signinged 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 lenth, 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 +} \ No newline at end of file