diff --git a/.github/generatePackageVersion.ps1 b/.github/generatePackageVersion.ps1 deleted file mode 100644 index c2154acde..000000000 --- a/.github/generatePackageVersion.ps1 +++ /dev/null @@ -1,13 +0,0 @@ -$GetFileVersionOutput = dotnet msbuild $PSScriptRoot/../dotnet/Directory.Build.props /t:GetFileVersionForPackage -"$GetFileVersionOutput" -match "(?<=FileVersion:)(.*)" > $null -$GetFileVersionOutput = $Matches[0] - -$NuGetPackageVersion = $GetFileVersionOutput -if ([System.Convert]::ToBoolean($Env:IsPrerelease)) { - $IsMaster = $Env:GIT_REF -match 'master$' - $VersionTag = @("trunk", "stable")[$IsMaster] - $Timestamp = (Get-Date).ToString("yyyyMMddHHmmss") - $NuGetPackageVersion = $NuGetPackageVersion + "-" + $VersionTag + "." + $Timestamp -} - -return $NuGetPackageVersion \ No newline at end of file diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index ce21e7985..fbdf96489 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -2,6 +2,11 @@ name: Build on: workflow_dispatch: + inputs: + skip-duplicates: + description: 'Whether to fail or skip duplicates when uploading to a package repository' + required: false + default: 'true' pull_request: branches: - 'master' @@ -22,47 +27,92 @@ jobs: runs-on: windows-latest + outputs: + NUGET_VERSION: ${{ steps.buildVariables.outputs.NUGET_PACKAGE_VERSION }} + LAST_COMMITTER: ${{ steps.buildVariables.outputs.LAST_COMMITTER }} + COMMIT_MESSAGE: ${{ steps.buildVariables.outputs.COMMIT_MESSAGE }} + SHOULD_DEPLOY: ${{ steps.buildVariables.outputs.SHOULD_DEPLOY }} + steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - - - name: Install .NET Core 5.0 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '5.0.x' - name: Install .NET 6 - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 with: dotnet-version: '6.0.x' - include-prerelease: True - - - uses: actions/setup-dotnet@v1 - with: - source-url: https://nuget.pkg.github.com/genexuslabs/index.json - env: - NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} + include-prerelease: false - name: Calculate environment variables - run: | - $IsPrerelease = !($Env:GIT_REF -match 'release-[0-9]+(?:\.[0-9]+)?$') - echo "IsPrerelease=$IsPrerelease" >> $env:GITHUB_ENV + id: buildVariables + run: | + $IsMaster = $false + + switch -regex ($Env:GIT_REF) { + 'master' { + $IsPrerelease = $true + $IsMaster = $true + + $SHOULD_DEPLOY = 'true' + } + + 'beta' { + $IsPrerelease = $true + + $SHOULD_DEPLOY = 'true' + } + + 'release-*' { + $IsPrerelease = $false + + $SHOULD_DEPLOY = 'true' + } + + default { + $IsPrerelease = $false + + $SHOULD_DEPLOY = 'false' + } + } $COMMIT_NUMBER = @($(git rev-list --count origin/master..), $(git rev-list --count HEAD))[$IsPrerelease] + $COMMIT_MESSAGE = $(git log -1 --pretty=%B) + $LAST_COMMITTER = $(git log -1 --pretty=format:%an) + + $GetFileVersionOutput = dotnet msbuild dotnet/Directory.Build.props /t:GetFileVersionForPackage /p:COMMIT_NUMBER=$COMMIT_NUMBER + "$GetFileVersionOutput" -match "(?<=FileVersion:)(.*)" > $null + $GetFileVersionOutput = $Matches[0] + + $NUGET_PACKAGE_VERSION = $GetFileVersionOutput + + if ($IsPrerelease -eq $true) { + $VersionTag = @("trunk", "stable")[$IsMaster] + $Timestamp = (Get-Date -AsUTC).ToString("yyyyMMddHHmmss") + $NUGET_PACKAGE_VERSION = $NUGET_PACKAGE_VERSION + "-" + $VersionTag + "." + $Timestamp + } + + Write-Output "Packge version to be used: $NUGET_PACKAGE_VERSION" + + echo "NUGET_PACKAGE_VERSION=$NUGET_PACKAGE_VERSION" >> $env:GITHUB_ENV + echo "IsPrerelease=$IsPrerelease" >> $env:GITHUB_ENV - echo "COMMIT_NUMBER=$COMMIT_NUMBER" >> $env:GITHUB_ENV + echo "::set-output name=NUGET_PACKAGE_VERSION::$NUGET_PACKAGE_VERSION" + echo "::set-output name=SHOULD_DEPLOY::$SHOULD_DEPLOY" + echo "::set-output name=LAST_COMMITTER::$LAST_COMMITTER" + echo "::set-output name=COMMIT_MESSAGE::$COMMIT_MESSAGE" - - name: Calculate package version + - name: Write SNK + if: github.repository_owner == 'GeneXusLabs' && steps.buildVariables.outputs.SHOULD_DEPLOY == 'true' env: - PackageVersionString: ./.github/generatePackageVersion.ps1 + SNK_BASE64: ${{ secrets.ARTECH_SNK_BASE64 }} run: | - $NuGetPackageVersion = & "$Env:PackageVersionString" - - Write-Output "Packge version to be used: $NuGetPackageVersion" + $artech_snk_path = Join-Path (Get-Item .).FullName "Artech.snk" + $bytes = [Convert]::FromBase64String($Env:SNK_BASE64) + [IO.File]::WriteAllBytes($artech_snk_path, $bytes) - echo "NuGetPackageVersion=$NuGetPackageVersion" >> $env:GITHUB_ENV + echo "ARTECH_SNK_FILE=$artech_snk_path" >> $env:GITHUB_ENV - name: Restore packages run: dotnet restore $Env:SolutionFile @@ -74,4 +124,113 @@ jobs: run: dotnet test $Env:SolutionFile --no-restore --no-build --configuration $Env:Configuration - name: Pack - run: dotnet pack $Env:SolutionFile --no-restore --no-build --configuration $Env:Configuration /p:Version=$Env:NuGetPackageVersion + run: dotnet pack $Env:SolutionFile --no-restore --no-build --configuration $Env:Configuration /p:Version=$Env:NUGET_PACKAGE_VERSION + + - name: Sign packages + if: github.repository_owner == 'GeneXusLabs' && steps.buildVariables.outputs.SHOULD_DEPLOY == 'true' + env: + TIMESTAMPER_URL: ${{ secrets.CODE_SIGN_CERTIFICATE_TIMESTAMPER_URL }} + PFX_BASE64: ${{ secrets.CODE_SIGN_CERTIFICATE_BASE64 }} + PFX_PASS: ${{ secrets.CODE_SIGN_CERTIFICATE_PASSWORD }} + run: | + $codesign_pfx = "code_sign_cert.pfx" + $bytes = [Convert]::FromBase64String($Env:PFX_BASE64) + [IO.File]::WriteAllBytes($codesign_pfx, $bytes) + + Get-ChildItem ".\dotnet\*.nupkg" -Recurse | ForEach-Object { + dotnet nuget sign $_.FullName --certificate-path $codesign_pfx --certificate-password $Env:PFX_PASS --timestamper $Env:TIMESTAMPER_URL + } + + - name: Configure Azure Artifacts feed + if: github.repository_owner == 'GeneXusLabs' && steps.buildVariables.outputs.SHOULD_DEPLOY == 'true' + env: + AzureArtifactsPrereleaseFeedURL: https://pkgs.dev.azure.com/genexuslabs/13fb82d9-57a8-49ef-95bb-0ec8324e470c/_packaging/dotnet-prereleases/nuget/v3/index.json + AzureArtifactsReleaseFeedURL: https://pkgs.dev.azure.com/genexuslabs/13fb82d9-57a8-49ef-95bb-0ec8324e470c/_packaging/dotnet-releases/nuget/v3/index.json + run: | + $IsPrerelease = [System.Convert]::ToBoolean($Env:IsPrerelease) + $AZURE_ARTIFACTS_URL = @("$Env:AzureArtifactsReleaseFeedURL", "$Env:AzureArtifactsPrereleaseFeedURL")[$IsPrerelease] + + dotnet nuget add source $AZURE_ARTIFACTS_URL --name AzureArtifacts --username genexuslabs --password ${{ secrets.AZURE_ARTIFACTS_TOKEN }} + + echo "AZURE_ARTIFACTS_URL=$AZURE_ARTIFACTS_URL" >> $env:GITHUB_ENV + + - name: Push packages + if: github.repository_owner == 'GeneXusLabs' && steps.buildVariables.outputs.SHOULD_DEPLOY == 'true' + env: + GPRFeedURL: https://nuget.pkg.github.com/genexuslabs/index.json + NuGetFeedURL: https://api.nuget.org/v3/index.json + run: | + $IsPrerelease = [System.Convert]::ToBoolean($Env:IsPrerelease) + + $totalPackages = 0 + $pushedToAzure = 0 + $pushedToGitHub = 0 + $pushedToNuget = 0 + + Get-ChildItem ".\dotnet\*.nupkg" -Recurse | ForEach-Object { + $PushToGitHubArgs = @("nuget", "push", $_.FullName, "--source", $Env:GPRFeedURL, "--api-key", "${{ secrets.SECURE_TOKEN }}") + $PushToNugetArgs = @("nuget", "push", $_.FullName, "--source", $Env:NuGetFeedURL, "--api-key", "${{ secrets.NUGET_ORG_TOKEN }}") + $PushToAzureArgs = @("nuget", "push", $_.FullName, "--source", $Env:AZURE_ARTIFACTS_URL, "--api-key", "DUMMY-KEY") + + if ([string]::IsNullOrEmpty("${{ github.event.inputs.skip-duplicates }}") ) { + $skipDuplicates = $true + } else { + $skipDuplicates = [System.Convert]::ToBoolean("${{ github.event.inputs.skip-duplicates }}") + } + + if ($skipDuplicates) { + $PushToNugetArgs += "--skip-duplicate" + $PushToGitHubArgs += "--skip-duplicate" + $PushToAzureArgs += "--skip-duplicate" + } + + dotnet $PushToAzureArgs + $pushedToAzure += 1 + + if (!$IsPrerelease) { + dotnet $PushToGitHubArgs + $pushedToGitHub += 1 + + dotnet $PushToNugetArgs + $pushedToNuget += 1 + } + + $totalPackages += 1 + } + + Write-Output "Number of packages found: $totalPackages" + + Write-Output "Number of packages pushed to Azure Artifacts: $pushedToAzure" + Write-Output "Number of packages pushed to GitHub: $pushedToGitHub" + Write-Output "Number of packages pushed to Nuget.org: $pushedToNuget" + + dispatch-build: + name: Dispatch build result + needs: build + if: github.repository_owner == 'GeneXusLabs' && needs.build.outputs.SHOULD_DEPLOY == 'true' + + runs-on: ubuntu-latest + + concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: Checkout action + uses: actions/checkout@v3 + with: + repository: genexuslabs/dispatch-build-result + ref: releases/v2 + token: ${{ secrets.SECURE_TOKEN }} + path: ./tmp/.github/actions/dispatch-build-result + + - name: Dispatch build result + uses: ./tmp/.github/actions/dispatch-build-result + with: + component-name: ${{ github.event.inputs.repository }} + branch-ref: ${{ env.GIT_REF }} + new-version: ${{ needs.build.outputs.NUGET_VERSION }} + committer: ${{ needs.build.outputs.LAST_COMMITTER }} + commit-message: ${{ needs.build.outputs.COMMIT_MESSAGE }} + token: ${{ secrets.SECURE_TOKEN }} + diff --git a/.github/workflows/External-Storage-Tests.yml b/.github/workflows/External-Storage-Tests.yml index 95b0210a8..5fae5df91 100644 --- a/.github/workflows/External-Storage-Tests.yml +++ b/.github/workflows/External-Storage-Tests.yml @@ -24,46 +24,15 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - - - name: Install .NET Core 5.0 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '5.0.x' - name: Install .NET 6 - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 with: dotnet-version: '6.0.x' - include-prerelease: True - - - uses: actions/setup-dotnet@v1 - with: - source-url: https://nuget.pkg.github.com/genexuslabs/index.json - env: - NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - name: Calculate environment variables - run: | - $IsPrerelease = !($Env:GIT_REF -match 'release-[0-9]+(?:\.[0-9]+)?$') - echo "IsPrerelease=$IsPrerelease" >> $env:GITHUB_ENV - - $COMMIT_NUMBER = @($(git rev-list --count origin/master..), $(git rev-list --count HEAD))[$IsPrerelease] - - echo "COMMIT_NUMBER=$COMMIT_NUMBER" >> $env:GITHUB_ENV - - - name: Calculate package version - env: - PackageVersionString: ./.github/generatePackageVersion.ps1 - run: | - $NuGetPackageVersion = & "$Env:PackageVersionString" - - Write-Output "Packge version to be used: $NuGetPackageVersion" - - echo "NuGetPackageVersion=$NuGetPackageVersion" >> $env:GITHUB_ENV - + - name: Restore packages run: dotnet restore $Env:SolutionFile diff --git a/.github/workflows/ProcessCommit.yml b/.github/workflows/ProcessCommit.yml deleted file mode 100644 index bd3fc0cf4..000000000 --- a/.github/workflows/ProcessCommit.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Process commit -on: - workflow_dispatch: - push: - branches: - - 'master' - - 'beta' - - 'release-*' - -jobs: - dispatchWorkflow: - runs-on: [ubuntu-latest] - - steps: - - name: Dispatch Workflow - run: > - curl -X POST - -H 'Accept: application/vnd.github.v3+json' - -H 'Authorization: token ${{ secrets.SECURE_TOKEN }}' - --silent --show-error --fail - ${{ secrets.BUILD_WORKFLOW_DISPATCH }} - -d '{ - "ref":"main", - "inputs": { - "repository": "${{ github.repository }}", - "ref": "${{ github.ref }}", - "sha": "${{ github.sha }}", - "build-file": "dotnet\\DotNetStandardClasses.sln", - "package-version": ".\\.github\\generatePackageVersion.ps1", - "packages-path": ".\\dotnet\\*.nupkg", - "skip-duplicates": "true" - } - }' diff --git a/.github/workflows/veracode.yml b/.github/workflows/veracode.yml new file mode 100644 index 000000000..6a8bbb934 --- /dev/null +++ b/.github/workflows/veracode.yml @@ -0,0 +1,103 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow will initiate a Veracode Static Analysis Pipeline scan, return a results.json and convert to SARIF for upload as a code scanning alert + +name: Veracode Static Analysis Pipeline Scan + +on: + workflow_dispatch: + + push: + branches: + - 'master' + - 'beta' + - 'release-*' + + #Run at the end of every day + schedule: + - cron: '0 0 * * *' + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +permissions: + contents: read + +jobs: + # This workflow contains a job to build and submit pipeline scan, you will need to customize the build process accordingly and make sure the artifact you build is used as the file input to the pipeline scan file parameter + build-and-pipeline-scan: + env: + ZipFilename: netClassesForScan.zip + + # The type of runner that the job will run on + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + + runs-on: windows-latest + + steps: + + - name: Checkout repository + uses: actions/checkout@v2 + with: + repository: '' + + - uses: actions/setup-dotnet@v1 + with: + source-url: https://nuget.pkg.github.com/genexuslabs/index.json + env: + NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Build + run: | + $veracodesolution = "VeracodeSolution" + dotnet new sln --name $veracodesolution --output dotnet --force + dotnet msbuild dotnet\DotNetStandardClasses.sln /t:DumpProjects -p:DumpSolutionName=$veracodesolution /m:1 + dotnet msbuild dotnet\Directory.Build.targets /t:PublishForAnalyzer -p:DumpSolutionName=$veracodesolution + + - name: Create package for Veracode scan + shell: powershell + run: | + Compress-Archive -Path .out\* $env:ZipFilename + + - name: Archive zip to analyze + uses: actions/upload-artifact@v3 + with: + name: netclasses_zip_to_artifacts + path: netClassesForScan.zip + retention-days: 15 + + - name: Download Veracode Static Analysis Pipeline scan jar + shell: powershell + run: | + Invoke-WebRequest -Uri "https://downloads.veracode.com/securityscan/pipeline-scan-LATEST.zip" -OutFile "pipeline-scan.zip" + Expand-Archive "pipeline-scan.zip" -DestinationPath ".veracode" -Force + + - name: Upload package for scan + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Execute scan + run: java -jar ".veracode\pipeline-scan.jar" --veracode_api_id "${{secrets.VERACODE_API_ID}}" --veracode_api_key "${{secrets.VERACODE_API_KEY}}" --fail_on_severity="Very High, High" --file $env:ZipFilename + continue-on-error: false + - name: Convert pipeline scan output to SARIF format + id: convert + uses: veracode/veracode-pipeline-scan-results-to-sarif@ff08ae5b45d5384cb4679932f184c013d34da9be + with: + pipeline-results-json: results.json + source-base-path-1: "^.*/${{ github.event.repository.name }}/dotnet/:dotnet/" + + - uses: github/codeql-action/upload-sarif@v1 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: veracode-results.sarif + + - uses: actions/upload-artifact@v3 + with: + name: veracode_json_and_sarif_results + path: | + results.json + veracode-results.sarif + retention-days: 15 diff --git a/.gitignore b/.gitignore index dfc726d36..9c40adaa6 100644 --- a/.gitignore +++ b/.gitignore @@ -361,3 +361,6 @@ build /dotnet/src/dotnetcore/GxDataInitialization/net6.0/GXDataInitialization.deps.json /dotnet/src/dotnetcore/GxNetCoreStartup/net6.0/GxNetCoreStartup.deps.json /dotnet/src/dotnetcore/Reor/net6.0/Reor.deps.json +.out +/dotnet/Veracode.sln +/dotnet/VeracodeSolution.sln diff --git a/README.md b/README.md index 3e6ada390..abe01143e 100644 --- a/README.md +++ b/README.md @@ -83,20 +83,26 @@ For the following steps must be executed from inside ```dotnet``` directory: ## How to test your changes with a GeneXus installation? - ```dotnet msbuild /t:build;CopyAssemblies DotNetStandardClasses.sln``` -It compiles the solution and copies all the .NET Framework assemblies to the folder build/gxnet*/bin**. Then, you can copy those files to a GeneXus installation or to your web application directory. +It compiles the solution and copies all the .NET Framework assemblies to the folder dotnet/build. Then, you can copy those files to a GeneXus installation or to your web application directory. You can use the following parameters to customize the deploy: - TargetFramework: only the assemblies that are generated for this framework will be deployed. Valid values are: `net462` (for GeneXus NET Framework generator) and `net6` (for GeneXus NET generator). -- DeployDirectory: specifies a GeneXus installation directory. +- DeployDirectory: specifies the target directory to copy assemblies, by default it is dotnet\bin Samples: -- ```dotnet msbuild /t:build;CopyAssemblies /p:DeployDirectory=C:\Genexus /p:TargetFramework=net462 DotNetStandardClasses.sln``` -It copies .NET framework assemblies to the folder C:\Genexus\gxnet\bin +- ```dotnet msbuild /t:CopyAssemblies /p:TargetFramework=net6.0 DotNetStandardClasses.sln ``` -- ```dotnet msbuild /t:CopyAssemblies /p:DeployDirectory=C:\Genexus /p:TargetFramework=net6.0 DotNetStandardClasses.sln ``` +It copies .NET 6 assemblies to the folder dotnet\bin + +- ```dotnet msbuild /t:CopyAssemblies /p:DeployDirectory=C:\KB\NetModel\web\bin /p:TargetFramework=net6.0 DotNetStandardClasses.sln ``` + +It copies .NET 6 assemblies to the folder C:\KB\NetModel\web\bin + +- ```dotnet msbuild /t:build;CopyAssemblies /p:DeployDirectory=C:\KB\CSharpModel\web\bin /p:TargetFramework=net462 DotNetStandardClasses.sln``` + +It builds the solution and copies .NET framework assemblies to the folder C:\KB\CSharpModel\web\bin -It copies .NET 6 assemblies to the folder C:\Genexus\gxnetcore\bin ## Advanced information @@ -109,7 +115,7 @@ Suppose you do a fix in GxClasses project. In order to get that fix in your gene - A new .snk file can be created with the command [sn.exe](https://docs.microsoft.com/en-us/dotnet/framework/tools/sn-exe-strong-name-tool) -k keyPair.snk 2. Build DotNetStandardClasses.sln and copy ```DotNetClasses\dotnet\src\dotnetframework\GxClasses\bin\Release\net462\GxClasses.dll``` to your ```\CSharpModel\web\bin directory``` 3. Patch all the ```\CSharpModel\web\bin``` assemblies to reference the new GxClasses.dll. To do this run [UpdateAssemblyReference tool](dotnet/tools) with the following parameters - ```UpdateAssemblyReference.exe -assembly \CSharpModel\web\bin\GxClasses.dll -d \CSharpModel\web\bin``` + ```UpdateAssemblyReference.exe -a \CSharpModel\web\bin\GxClasses.dll -d \CSharpModel\web\bin``` - To get UpdateAssemblyReference.exe build [UpdateAssemblyReference.sln](dotnet/tools/updateassemblyreference/UpdateAssemblyReference.sln) 4. Since GxClasses references other assemblies, it is needed to keep that references unchanged. So this command will patch the new GxClasses.dll to reference the original ones: diff --git a/dotnet/Directory.Build.props b/dotnet/Directory.Build.props index 3f80c42e0..a4c7a6535 100644 --- a/dotnet/Directory.Build.props +++ b/dotnet/Directory.Build.props @@ -3,7 +3,7 @@ 11.0.0.0 1 $([MSBuild]::Add($(MajorFileVersion), 100)) - 19 + 20 $(COMMIT_NUMBER) 0 $(MajorFileVersion).$(MinorFileVersion).$(RevisionFileVersion) @@ -32,13 +32,6 @@ true True - - - gxnetcore\bin - - - gxnet\bin - diff --git a/dotnet/Directory.Build.targets b/dotnet/Directory.Build.targets index 0704d7080..d585c039e 100644 --- a/dotnet/Directory.Build.targets +++ b/dotnet/Directory.Build.targets @@ -12,18 +12,16 @@ $(MSBuildThisFileDirectory)\src\resources\Default_App.ico - - $(MSBuildThisFileDirectory)build - + + TempSolution + net6 - - $(DeployDirectory)\ - - - + + $(MSBuildThisFileDirectory)bin\$(TargetFramework) + - + all @@ -31,50 +29,17 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + - - - + + + + + + \ No newline at end of file diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 9013ef07d..a7fdd3ea7 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -69,9 +69,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GXGoogleCloud", "src\dotnet EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dynservice", "dynservice", "{A14C2C2C-ACE3-4712-A527-E4E5F02729FA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynService.Core", "src\dotnetframework\DynService.Core\DynService.Core.csproj", "{B0DEB9ED-9E0A-42E3-BBE1-9F70DD78DC93}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynService.Core", "src\dotnetcommon\DynService.Core\DynService.Core.csproj", "{B0DEB9ED-9E0A-42E3-BBE1-9F70DD78DC93}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynService.DynamoDB", "src\dotnetframework\DynService.Dynamo\DynService.DynamoDB.csproj", "{4DC1C813-E7C1-442E-B7D6-C9B932A55759}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynService.DynamoDB", "src\dotnetcommon\DynService.Dynamo\DynService.DynamoDB.csproj", "{4DC1C813-E7C1-442E-B7D6-C9B932A55759}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynService.Fabric", "src\dotnetframework\DynServiceFabric\DynService.Fabric.csproj", "{42D048EC-29C5-4553-B301-A6A5A76A7FB8}" EndProject @@ -119,8 +119,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetUnitTest", "test\DotN EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dynservice", "dynservice", "{79C9ECC6-2935-4C43-BF32-94698547F584}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynService.Core", "src\dotnetcore\DynService\Core\DynService.Core.csproj", "{E2FB8843-503A-4A22-923E-B12510233127}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynServiceOData", "src\dotnetcore\DynService\OData\DynServiceOData.csproj", "{2238FCB1-3A83-46C2-873E-82DA4266069D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azurefunctionhandlers", "azurefunctionhandlers", "{BD804A75-9F3F-416C-BF6B-D3DF6C4A8DC0}" @@ -186,6 +184,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\.editorconfig = ..\.editorconfig EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dynservice", "dynservice", "{C264F34E-2CE0-4DCA-B22D-4155821BE611}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GxXsl", "src\dotnetcore\GxXsl\GxXsl.csproj", "{30E7E437-F9B0-42B8-9144-A8E8F972B462}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GXAzureQueue", "src\dotnetcore\Providers\Messaging\GXAzureQueue\GXAzureQueue.csproj", "{0CED9D4D-EE7C-4E19-9FC6-D4BBCB04DA97}" @@ -218,6 +218,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GXMessageBroker", "src\dotn EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GXAzureServiceBus", "src\dotnetcore\Providers\Messaging\GXAzureServiceBus\GXAzureServiceBus.csproj", "{F8ABEA82-F823-4E9C-96FA-26AF24C932E0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectHealthTest", "test\ProjectHealthTest\ProjectHealthTest.csproj", "{65048104-212A-4819-AECF-89CA9C08C83F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -408,10 +410,6 @@ Global {251CCD53-21B3-4EBE-8627-49885C4E98B9}.Debug|Any CPU.Build.0 = Debug|Any CPU {251CCD53-21B3-4EBE-8627-49885C4E98B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {251CCD53-21B3-4EBE-8627-49885C4E98B9}.Release|Any CPU.Build.0 = Release|Any CPU - {E2FB8843-503A-4A22-923E-B12510233127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E2FB8843-503A-4A22-923E-B12510233127}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E2FB8843-503A-4A22-923E-B12510233127}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E2FB8843-503A-4A22-923E-B12510233127}.Release|Any CPU.Build.0 = Release|Any CPU {2238FCB1-3A83-46C2-873E-82DA4266069D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2238FCB1-3A83-46C2-873E-82DA4266069D}.Debug|Any CPU.Build.0 = Debug|Any CPU {2238FCB1-3A83-46C2-873E-82DA4266069D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -520,6 +518,10 @@ Global {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}.Debug|Any CPU.Build.0 = Debug|Any CPU {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}.Release|Any CPU.ActiveCfg = Release|Any CPU {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}.Release|Any CPU.Build.0 = Release|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Release|Any CPU.Build.0 = Release|Any CPU {48430E50-043A-47A2-8278-B86A4420758A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {48430E50-043A-47A2-8278-B86A4420758A}.Debug|Any CPU.Build.0 = Debug|Any CPU {48430E50-043A-47A2-8278-B86A4420758A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -567,8 +569,8 @@ Global {F6372249-AF37-4455-B572-5BDF8DE2ACC8} = {F82842DA-F15E-49C5-993E-4C269818FF1F} {E9072D95-D116-4D4B-B981-46146BCDE052} = {F82842DA-F15E-49C5-993E-4C269818FF1F} {A14C2C2C-ACE3-4712-A527-E4E5F02729FA} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} - {B0DEB9ED-9E0A-42E3-BBE1-9F70DD78DC93} = {A14C2C2C-ACE3-4712-A527-E4E5F02729FA} - {4DC1C813-E7C1-442E-B7D6-C9B932A55759} = {A14C2C2C-ACE3-4712-A527-E4E5F02729FA} + {B0DEB9ED-9E0A-42E3-BBE1-9F70DD78DC93} = {C264F34E-2CE0-4DCA-B22D-4155821BE611} + {4DC1C813-E7C1-442E-B7D6-C9B932A55759} = {C264F34E-2CE0-4DCA-B22D-4155821BE611} {42D048EC-29C5-4553-B301-A6A5A76A7FB8} = {A14C2C2C-ACE3-4712-A527-E4E5F02729FA} {9C521E63-7B6F-4AD3-ACB5-132175D9413A} = {A14C2C2C-ACE3-4712-A527-E4E5F02729FA} {277490D7-8834-4722-9084-E894F804C66A} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} @@ -591,7 +593,6 @@ Global {55297803-2DE8-48C4-AB65-9D19E77614E1} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {251CCD53-21B3-4EBE-8627-49885C4E98B9} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {79C9ECC6-2935-4C43-BF32-94698547F584} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} - {E2FB8843-503A-4A22-923E-B12510233127} = {79C9ECC6-2935-4C43-BF32-94698547F584} {2238FCB1-3A83-46C2-873E-82DA4266069D} = {79C9ECC6-2935-4C43-BF32-94698547F584} {BD804A75-9F3F-416C-BF6B-D3DF6C4A8DC0} = {C6AFB6A3-FF0B-4970-B1F1-10BCD3D932B2} {41E1D031-799F-484F-85DE-7A30AF1A6FBA} = {BD804A75-9F3F-416C-BF6B-D3DF6C4A8DC0} @@ -621,6 +622,7 @@ Global {911BC7CC-4A07-408F-BA20-8BAB5355BE84} = {C8590651-46B6-4681-A6A0-0850B5A9A697} {B59F76D8-FDB2-4F51-89DB-F15E9BDFF1DC} = {420E8A4A-11D9-42E9-BFB7-4325EA7330B8} {D97E17A4-C945-4BF3-957E-F73142C4C6D0} = {947E032A-C385-4586-96E3-FC7D2767F082} + {C264F34E-2CE0-4DCA-B22D-4155821BE611} = {F1E13DF4-9F50-41A2-9DC3-04B673B21032} {30E7E437-F9B0-42B8-9144-A8E8F972B462} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} {0CED9D4D-EE7C-4E19-9FC6-D4BBCB04DA97} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} {30159B0F-BE61-4DB7-AC02-02851426BE4B} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} @@ -634,6 +636,7 @@ Global {DCEC0B38-93B6-4003-81E6-9FBC2BB4F163} = {7BA5A2CE-7992-4F87-9D84-91AE4D046F5A} {F8BA0D65-267D-491F-BFAB-33F5E5B61AD7} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3} = {7BA5A2CE-7992-4F87-9D84-91AE4D046F5A} + {65048104-212A-4819-AECF-89CA9C08C83F} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {48430E50-043A-47A2-8278-B86A4420758A} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {3B1B5706-E896-4CEB-A551-E30226303BDB} = {4C43F2DA-59E5-46F5-B691-195449498555} {F8ABEA82-F823-4E9C-96FA-26AF24C932E0} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} diff --git a/dotnet/src/dotnetcommon/DynService.Core/DynService.Core.csproj b/dotnet/src/dotnetcommon/DynService.Core/DynService.Core.csproj new file mode 100644 index 000000000..6d8118577 --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Core/DynService.Core.csproj @@ -0,0 +1,21 @@ + + + net462;net6.0 + GeneXus.Data.NTier + GeneXus.Data.DynService.Core + CA1812 + Dynservice + GeneXus.DynService.Core + + + + NETCORE + + + + + + + + + \ No newline at end of file diff --git a/dotnet/src/dotnetframework/DynService.Core/DynServiceCommon.cs b/dotnet/src/dotnetcommon/DynService.Core/DynServiceCommon.cs similarity index 83% rename from dotnet/src/dotnetframework/DynService.Core/DynServiceCommon.cs rename to dotnet/src/dotnetcommon/DynService.Core/DynServiceCommon.cs index 77cf83643..695113439 100644 --- a/dotnet/src/dotnetframework/DynService.Core/DynServiceCommon.cs +++ b/dotnet/src/dotnetcommon/DynService.Core/DynServiceCommon.cs @@ -16,21 +16,20 @@ namespace GeneXus.Data.NTier { public class Query { - private object mDataStoreHelper; - public string TableName { get; set; } = String.Empty; - public string[] Projection { get; set; } = Array.Empty(); - public string[] OrderBys { get; set; } = Array.Empty(); - public string[] Filters { get; set; } = Array.Empty(); - public string[] AssignAtts { get; set; } = Array.Empty(); - public IODataMap2[] SelectList { get; set; } = Array.Empty(); - public VarValue[] Vars { get; set; } = Array.Empty(); + public IEnumerable Projection { get; set; } = Array.Empty(); + public IEnumerable OrderBys { get; set; } = Array.Empty(); + public IEnumerable Filters { get; set; } = Array.Empty(); + private List> mAssignAtts; + public IEnumerable> AssignAtts { get { return mAssignAtts ?? Array.Empty>() as IEnumerable>; } } + public IEnumerable SelectList { get; set; } = Array.Empty(); + + private List mVarValues; + public IEnumerable Vars { get { return (mVarValues ?? Array.Empty() as IEnumerable); } } public CursorType CursorType { get; set; } = CursorType.Select; - public Query(object dataStoreHelper) - { - mDataStoreHelper = dataStoreHelper; - } + public Query(object dataStoreHelper) { } + public Query For(string v) { TableName = v; @@ -54,9 +53,10 @@ public Query Filter(string[] filters) return this; } - public Query Set(string[] assignAtts) + public Query Set(string name, string value) { - AssignAtts = assignAtts; + mAssignAtts = mAssignAtts ?? new List>(); + mAssignAtts.Add(new KeyValuePair(name, value)); return this; } @@ -66,11 +66,6 @@ public Query SetMaps(IODataMap2[] iODataMap) return this; } - public Query SetVars(VarValue[] vars) - { - Vars = vars; - return this; - } public Query SetType(CursorType cType) { @@ -78,6 +73,12 @@ public Query SetType(CursorType cType) return this; } + public Query AddConst(GXType gxType, object parm) + { + mVarValues = mVarValues ?? new List(); + mVarValues.Add(new VarValue($":const{ mVarValues.Count + 1 }", gxType, parm)); + return this; + } } public class VarValue @@ -89,24 +90,18 @@ public class VarValue public VarValue(string name, GXType type, object value) { Name = name; + Type = type; Value = value; } } - public class QueryExpression - { - public string For { get; set; } - internal string[] Select { get; set; } - } - - public interface IODataMap2 { object GetValue(IOServiceContext serviceContext, RecordEntryRow currentEntry); string GetName(IOServiceContext serviceContext); - void SetValue(IOServiceContext serviceContext, RecordEntryRow currentEntry, object value); + void SetValue(RecordEntryRow currentEntry, object value); } @@ -129,7 +124,7 @@ public virtual object GetValue(IOServiceContext context, RecordEntryRow currentE throw new NotImplementedException(); } - public virtual void SetValue(IOServiceContext context, RecordEntryRow currentEntry, object value) + public virtual void SetValue(RecordEntryRow currentEntry, object value) { throw new NotImplementedException(); } @@ -157,7 +152,15 @@ public interface IODataMap void SetValue(IDictionary currentEntry, object value); } - public abstract class DynServiceDataStoreHelper : DataStoreHelperBase + public abstract class DynServiceDataStoreHelperBase : DataStoreHelperBase + { + public static object InvalidQuery(string msg) + { + throw new ServiceException(msg); + } + } + + public abstract class DynServiceDataStoreHelper : DynServiceDataStoreHelperBase { public abstract Guid GetParmGuid(IDataParameterCollection parms, string parm); public abstract string GetParmStr(IDataParameterCollection parms, string parm); diff --git a/dotnet/src/dotnetcommon/DynService.Core/GlobalSuppressions.cs b/dotnet/src/dotnetcommon/DynService.Core/GlobalSuppressions.cs new file mode 100644 index 000000000..3dc76b4ab --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Core/GlobalSuppressions.cs @@ -0,0 +1,5 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + diff --git a/dotnet/src/dotnetframework/DynService.Core/Properties/AssemblyInfo.cs b/dotnet/src/dotnetcommon/DynService.Core/Properties/AssemblyInfo.cs similarity index 100% rename from dotnet/src/dotnetframework/DynService.Core/Properties/AssemblyInfo.cs rename to dotnet/src/dotnetcommon/DynService.Core/Properties/AssemblyInfo.cs diff --git a/dotnet/src/dotnetcommon/DynService.Dynamo/DynService.DynamoDB.csproj b/dotnet/src/dotnetcommon/DynService.Dynamo/DynService.DynamoDB.csproj new file mode 100644 index 000000000..cafcef4b2 --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynService.DynamoDB.csproj @@ -0,0 +1,31 @@ + + + net462;net6.0 + GeneXus.Data.NTier + GeneXus.Data.DynService.DynamoDB + false + DynamoDB + GeneXus.DynService.DynamoDB + + + + NETCORE + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBConnection.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBConnection.cs new file mode 100644 index 000000000..f3b2acf9d --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBConnection.cs @@ -0,0 +1,340 @@ +using Amazon; +using Amazon.DynamoDBv2; +using Amazon.DynamoDBv2.Model; +using Amazon.Runtime; +using GeneXus.Data.Dynamo; +using GeneXus.Data.NTier.DynamoDB; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; +using System.Linq; +using System.Net; +using System.Text; +using GeneXus.Cache; + +namespace GeneXus.Data.NTier +{ + + public class DynamoDBService: GxService + { + public DynamoDBService(string id, string providerId): base(id, providerId, typeof(DynamoDBConnection)) + { + + } + + public override IDataReader GetCacheDataReader(CacheItem item, bool computeSize, string keyCache) + { + return new GxDynamoDBCacheDataReader(item, computeSize, keyCache); + } + } + + public class DynamoDBConnection : ServiceConnection + { + private readonly string CLIENT_ID = "User Id"; + private readonly string CLIENT_SECRET = "password"; + private readonly string REGION = "region"; + private readonly string LOCAL_URL = "LocalUrl"; + private readonly char[] SHARP_CHARS = new char[] { '#' }; + private AmazonDynamoDBClient mDynamoDB; + private AmazonDynamoDBConfig mConfig; + private AWSCredentials mCredentials; + private RegionEndpoint mRegion = RegionEndpoint.USEast1; + + private void InitializeDBConnection() + { + DbConnectionStringBuilder builder = new DbConnectionStringBuilder(false); + builder.ConnectionString = this.ConnectionString; + mConfig = new AmazonDynamoDBConfig(); + string mLocalUrl = null; + if (builder.TryGetValue(LOCAL_URL, out object localUrl)) + { + mLocalUrl = localUrl.ToString(); + } + if (builder.TryGetValue(CLIENT_ID, out object clientId) && builder.TryGetValue(CLIENT_SECRET, out object clientSecret)) + { + mCredentials = new BasicAWSCredentials(clientId.ToString(), clientSecret.ToString()); + } + if (builder.TryGetValue(REGION, out object region)) + { + mRegion = RegionEndpoint.GetBySystemName(region.ToString()); + } + + if (localUrl != null) + { + mConfig.ServiceURL = mLocalUrl; + if (region != null) + mConfig.AuthenticationRegion = region as string; + } + else + mConfig.RegionEndpoint = mRegion; + } + + private void Initialize() + { + InitializeDBConnection(); + State = ConnectionState.Executing; + + mDynamoDB = new AmazonDynamoDBClient(mCredentials, mConfig); + } + + private const string FILTER_PATTERN = @"\((.*) = :(.*)\)"; + + public override int ExecuteNonQuery(ServiceCursorDef cursorDef, IDataParameterCollection parms, CommandBehavior behavior) + { + Initialize(); + DynamoQuery query = cursorDef.Query as DynamoQuery; + bool isInsert = query.CursorType == ServiceCursorDef.CursorType.Insert; + + Dictionary values = new Dictionary(); + Dictionary expressionAttributeNames = null; + HashSet mappedNames = null; + string keyItemForUpd = query.PartitionKey; + if (keyItemForUpd != null && keyItemForUpd.StartsWith("#")) + { + expressionAttributeNames = new Dictionary(); + mappedNames = mappedNames ?? new HashSet(); + string keyName = keyItemForUpd.Substring(1); + expressionAttributeNames.Add(keyItemForUpd, keyName); + mappedNames.Add(keyName); + } + foreach (KeyValuePair asg in query.AssignAtts) + { + string name = asg.Key; + if (name.StartsWith("#")) + { + if (!isInsert) + { + expressionAttributeNames = new Dictionary(); + mappedNames = mappedNames ?? new HashSet(); + string keyName = name.Substring(1); + expressionAttributeNames.Add(name, keyName); + mappedNames.Add(keyName); + } + name = name.Substring(1); + } + string parmName = asg.Value.Substring(1); + DynamoDBHelper.AddAttributeValue(isInsert ? name : $":{ name }", parmName, values, parms, query.Vars); + } + + Dictionary keyCondition = new Dictionary(); + + foreach (string keyFilter in query.KeyFilters.Concat(query.Filters)) + { + Match match = Regex.Match(keyFilter, FILTER_PATTERN); + if (match.Groups.Count > 1) + { + string varName = match.Groups[2].Value; + string name = match.Groups[1].Value.TrimStart(SHARP_CHARS); + VarValue varValue = query.Vars.FirstOrDefault(v => v.Name == $":{varName}"); + if (varValue != null) + keyCondition[name] = DynamoDBHelper.ToAttributeValue(varValue); + else + { + if (parms[varName] is ServiceParameter serviceParm) + keyCondition[name] = DynamoDBHelper.ToAttributeValue(serviceParm.DbType, serviceParm.Value); + } + } + } + AmazonDynamoDBRequest request; + AmazonWebServiceResponse response = null; + + switch (query.CursorType) + { + case ServiceCursorDef.CursorType.Select: + throw new NotImplementedException(); + + case ServiceCursorDef.CursorType.Delete: + request = new DeleteItemRequest() + { + TableName = query.TableName, + Key = keyCondition, + ConditionExpression = $"attribute_exists({ keyItemForUpd })", + ExpressionAttributeNames = expressionAttributeNames + }; + try + { +#if NETCORE + response = DynamoDBHelper.RunSync(() => mDynamoDB.DeleteItemAsync((DeleteItemRequest)request)); +#else + response = mDynamoDB.DeleteItem((DeleteItemRequest)request); +#endif + } + catch (ConditionalCheckFailedException recordNotFound) + { + throw new ServiceException(ServiceError.RecordNotFound, recordNotFound); + } + break; + case ServiceCursorDef.CursorType.Insert: + request = new PutItemRequest + { + TableName = query.TableName, + Item = values, + ConditionExpression = $"attribute_not_exists({ keyItemForUpd })", + ExpressionAttributeNames = expressionAttributeNames + }; + try + { +#if NETCORE + response = DynamoDBHelper.RunSync(() => mDynamoDB.PutItemAsync((PutItemRequest)request)); +#else + response = mDynamoDB.PutItem((PutItemRequest)request); +#endif + } + catch (ConditionalCheckFailedException recordAlreadyExists) + { + throw new ServiceException(ServiceError.RecordAlreadyExists, recordAlreadyExists); + } + break; + case ServiceCursorDef.CursorType.Update: + request = new UpdateItemRequest + { + TableName = query.TableName, + Key = keyCondition, + UpdateExpression = ToAttributeUpdates(keyCondition, values, mappedNames), + ConditionExpression = $"attribute_exists({ keyItemForUpd })", + ExpressionAttributeValues = values, + ExpressionAttributeNames = expressionAttributeNames + }; + try + { +#if NETCORE + response = DynamoDBHelper.RunSync(() => mDynamoDB.UpdateItemAsync((UpdateItemRequest)request)); +#else + response = mDynamoDB.UpdateItem((UpdateItemRequest)request); +#endif + } + catch (ConditionalCheckFailedException recordNotFound) + { + throw new ServiceException(ServiceError.RecordNotFound, recordNotFound); + } + break; + } + + return response?.HttpStatusCode == HttpStatusCode.OK ? 1 : 0; + } + + private string ToAttributeUpdates(Dictionary keyConditions, Dictionary values, HashSet mappedNames) + { + StringBuilder updateExpression = new StringBuilder(); + foreach (var item in values) + { + string keyName = item.Key.Substring(1); + if (!keyConditions.ContainsKey(keyName) && !keyName.StartsWith("AV", StringComparison.InvariantCulture)) + { + if (mappedNames?.Contains(keyName) == true) + keyName = $"#{keyName}"; + updateExpression.Append(updateExpression.Length == 0 ? "SET " : ", "); + updateExpression.Append($"{ keyName } = { item.Key }"); + } + } + return updateExpression.ToString(); + } + + public override IDataReader ExecuteReader(ServiceCursorDef cursorDef, IDataParameterCollection parms, CommandBehavior behavior) + { + + Initialize(); + DynamoQuery query = cursorDef.Query as DynamoQuery; + + try + { + CreateDynamoQuery(query, GetQueryValues(query, parms), out DynamoDBDataReader dataReader, out AmazonDynamoDBRequest req); + RequestWrapper reqWrapper = new RequestWrapper(mDynamoDB, req); + dataReader = new DynamoDBDataReader(cursorDef, reqWrapper); + return dataReader; + } + catch (AmazonDynamoDBException e) + { + if (e.ErrorCode == DynamoDBErrors.ValidationException && + e.Message.Contains(DynamoDBErrors.ValidationExceptionMessageKey)) + throw new ServiceException(ServiceError.RecordNotFound); // Handles special case where a string key attribute is filtered with an empty value which is not supported on DynamoDB but should yield a not record found in GX + throw e; + } + catch (AmazonServiceException e) { throw e; } + catch (Exception e) { throw e; } + } + + private Dictionary GetQueryValues(DynamoQuery query, IDataParameterCollection parms) + { + Dictionary values = new Dictionary(); + foreach (object parm in parms) + DynamoDBHelper.GXToDynamoQueryParameter(values, parm as ServiceParameter); + foreach (VarValue item in query.Vars) + values.Add(item.Name, DynamoDBHelper.ToAttributeValue(item)); + return values; + } + + private static void CreateDynamoQuery(DynamoQuery query, Dictionary values, out DynamoDBDataReader dataReader, out AmazonDynamoDBRequest req) + { + dataReader = null; + req = null; + Dictionary expressionAttributeNames = null; + foreach (string mappedName in query.SelectList.Where(selItem => (selItem as DynamoDBMap)?.NeedsAttributeMap == true).Select(selItem => selItem.GetName(NewServiceContext()))) + { + expressionAttributeNames = expressionAttributeNames ?? new Dictionary(); + string key = $"#{ mappedName }"; + string value = mappedName; + expressionAttributeNames.Add(key, value); + } + + bool issueScan = query is DynamoScan; + if (!issueScan) + { // Check whether a query has to be demoted to scan due to empty parameters + foreach (string keyFilter in query.KeyFilters) + { + Match match = Regex.Match(keyFilter, @".*(:.*)\).*"); + if (match.Groups.Count > 0) + { + string varName = match.Groups[1].Value; + if(values.TryGetValue(varName, out AttributeValue value) && value.S?.Length == 0) + { + issueScan = true; + break; + } + } + } + } + + if (issueScan) + { + ScanRequest scanReq; + IEnumerable allFilters = query.KeyFilters.Concat(query.Filters); + req = scanReq = new ScanRequest + { + TableName = query.TableName, + ProjectionExpression = String.Join(",", query.Projection), + FilterExpression = allFilters.Any() ? String.Join(" AND ", allFilters) : null, + ExpressionAttributeValues = values, + }; + if (expressionAttributeNames != null) + scanReq.ExpressionAttributeNames = expressionAttributeNames; + } + else + { + QueryRequest queryReq; + req = queryReq = new QueryRequest + { + TableName = query.TableName, + KeyConditionExpression = String.Join(" AND ", query.KeyFilters), + FilterExpression = query.Filters.Any() ? String.Join(" AND ", query.Filters) : null, + ExpressionAttributeValues = values, + ProjectionExpression = String.Join(",", query.Projection), + IndexName = query.Index, + ScanIndexForward = query.ScanIndexForward, + }; + if (expressionAttributeNames != null) + queryReq.ExpressionAttributeNames = expressionAttributeNames; + } + } + internal static IOServiceContext NewServiceContext() => null; + + } + + public class DynamoDBErrors + { + public const string ValidationException = "ValidationException"; + public const string ValidationExceptionMessageKey = "The AttributeValue for a key attribute cannot contain an empty string value."; + } +} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBDataReader.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBDataReader.cs similarity index 62% rename from dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBDataReader.cs rename to dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBDataReader.cs index 641fea832..cb659a2e4 100644 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBDataReader.cs +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBDataReader.cs @@ -1,24 +1,23 @@ using System; using System.Collections.Generic; using System.Data; +using System.Globalization; +using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Amazon.DynamoDBv2.Model; using GeneXus.Cache; -using GeneXus.Data.Dynamo; using GeneXus.Data.NTier; using GeneXus.Data.NTier.DynamoDB; -using log4net; namespace GeneXus.Data.Dynamo { public class DynamoDBDataReader : IDataReader { - private RequestWrapper mRequest; + private readonly RequestWrapper mRequest; private ResponseWrapper mResponse; - private int mCurrentPosition = -1; - private IODataMap2[] selectList; + private int mCurrentPosition; + private readonly IODataMap2[] selectList; + private DynamoDBRecordEntry currentEntry; private int ItemCount { @@ -36,24 +35,26 @@ private List> Items } } - public DynamoDBDataReader(ServiceCursorDef cursorDef, RequestWrapper request, IDataParameterCollection parameters) + private void CheckCurrentPosition() + { + if (currentEntry == null) + throw new ServiceException(ServiceError.RecordNotFound); + } + + public DynamoDBDataReader(ServiceCursorDef cursorDef, RequestWrapper request) { Query query = cursorDef.Query as Query; - selectList = query.SelectList; + selectList = query.SelectList.ToArray(); mRequest = request; mResponse = mRequest.Read(); + mCurrentPosition = -1; } public object this[string name] { get { - if (mCurrentPosition >= 0 && mCurrentPosition < ItemCount) - { - return Items[mCurrentPosition][name].S; - } - throw new ArgumentOutOfRangeException(nameof(name)); - + throw new NotImplementedException(); } } @@ -61,16 +62,7 @@ public object this[int i] { get { - if (mCurrentPosition >= 0 && mCurrentPosition < ItemCount) - { - int j = 0; - foreach (var col in Items[mCurrentPosition]) - { - if (j == i) - return col.Value.S; - } - } - throw new ArgumentOutOfRangeException(nameof(i)); + throw new NotImplementedException(); } } @@ -120,12 +112,13 @@ public void Dispose() public long getLong(int i) { - return Convert.ToInt64(GetAttValue(i).N); + return Convert.ToInt64(GetAttValueN(i)); } public bool GetBoolean(int i) { - return GetAttValue(i).BOOL; + AttributeValue value = GetAttValue(i); + return value.IsBOOLSet && value.BOOL; } public byte GetByte(int i) @@ -135,7 +128,11 @@ public byte GetByte(int i) public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) { - throw new NotImplementedException(); + MemoryStream ms = GetAttValue(i).B; + if (ms == null) + return 0; + ms.Seek(fieldOffset, SeekOrigin.Begin); + return ms.Read(buffer, bufferoffset, length); } public char GetChar(int i) @@ -145,8 +142,7 @@ public char GetChar(int i) public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) { - buffer = GetAttValue(i).S.ToCharArray(); - return buffer.Length; + throw new NotImplementedException(); } public IDataReader GetData(int i) @@ -161,29 +157,28 @@ public string GetDataTypeName(int i) public DateTime GetDateTime(int i) { - DateTime dt = new DateTime(); - DateTime.TryParse(GetAttValue(i).S, out dt); + DateTime.TryParse(GetAttValue(i).S, null, DateTimeStyles.AdjustToUniversal, out DateTime dt); return dt; } public decimal GetDecimal(int i) { - return decimal.Parse(GetAttValue(i).N); + return decimal.Parse(GetAttValueN(i)); } public double GetDouble(int i) { - return double.Parse(GetAttValue(i).N); + return double.Parse(GetAttValueN(i)); } public Type GetFieldType(int i) { - throw new NotImplementedException(); + return selectList[i].GetValue(DynamoDBConnection.NewServiceContext(), currentEntry).GetType(); } public float GetFloat(int i) { - return float.Parse(GetAttValue(i).N); + return float.Parse(GetAttValueN(i)); } public Guid GetGuid(int i) @@ -193,18 +188,18 @@ public Guid GetGuid(int i) public short GetInt16(int i) { - return short.Parse(GetAttValue(i).N); + return short.Parse(GetAttValueN(i)); } public int GetInt32(int i) { - return int.Parse(GetAttValue(i).N); + return int.Parse(GetAttValueN(i)); } public long GetInt64(int i) { - return long.Parse(GetAttValue(i).N); + return long.Parse(GetAttValueN(i)); } public string GetName(int i) @@ -214,14 +209,11 @@ public string GetName(int i) public int GetOrdinal(string name) { - int j = 0; - foreach (var col in Items[mCurrentPosition]) - { - if (col.Key.ToLower() == name.ToLower()) - return j; - j++; - } - throw new ArgumentOutOfRangeException(nameof(name)); + CheckCurrentPosition(); + int ordinal = currentEntry.CurrentRow.ToList().FindIndex(col => col.Key.ToLower() == name.ToLower()); + if (ordinal == -1) + throw new ArgumentOutOfRangeException(nameof(name)); + else return ordinal; } public DataTable GetSchemaTable() @@ -231,7 +223,7 @@ public DataTable GetSchemaTable() public string GetString(int i) { - return GetAttValue(i).S; + return DynamoDBHelper.GetString(GetAttValue(i)); } public object GetValue(int i) @@ -242,16 +234,13 @@ public object GetValue(int i) if (attValue.IsBOOLSet) { value = attValue.BOOL; - } - if (attValue.S != null) + }else if (attValue.S != null || attValue.IsLSet || attValue.IsMSet) { - value = attValue.S; - } - if (attValue.N != null) + value = DynamoDBHelper.GetString(attValue); + }else if (attValue.N != null) { value = attValue.N; - } - if (attValue.B != null) + }else if (attValue.B != null) { value = attValue.B; } @@ -260,9 +249,11 @@ public object GetValue(int i) private AttributeValue GetAttValue(int i) { - return (AttributeValue)selectList[i].GetValue(NewServiceContext(), new DynamoDBRecordEntry(Items[mCurrentPosition])); + return (AttributeValue)selectList[i].GetValue(DynamoDBConnection.NewServiceContext(), currentEntry); } + private string GetAttValueN(int i) => GetAttValue(i)?.N ?? "0"; + public int GetValues(object[] values) { System.Diagnostics.Debug.Assert(selectList.Length == values.Length, "Values mismatch"); @@ -281,12 +272,15 @@ public bool IsDBNull(int i) public bool NextResult() { mCurrentPosition++; - return (mCurrentPosition < ItemCount); + currentEntry = (mCurrentPosition < ItemCount) ? new DynamoDBRecordEntry(Items[mCurrentPosition]) : null; + return currentEntry != null; } public bool Read() - { - if (mCurrentPosition == ItemCount && mCurrentPosition > 0) + { + if (NextResult()) + return true; + else if (mCurrentPosition > 0 && mResponse.LastEvaluatedKey?.Count > 0) { mResponse = mRequest.Read(mResponse.LastEvaluatedKey); /* @@ -295,15 +289,11 @@ public bool Read() * The result set contains the last_evaluated_key field. If more data is available for the operation, * this key contains information about the last evaluated key. Otherwise, the key remains empty. * */ + mCurrentPosition = -1; + return NextResult(); } - mCurrentPosition++; - return (mCurrentPosition < ItemCount); + return false; } - internal IOServiceContext NewServiceContext() - { - return null; - } - } public class GxDynamoDBCacheDataReader : GxCacheDataReader @@ -316,8 +306,7 @@ public GxDynamoDBCacheDataReader(CacheItem cacheItem, bool computeSize, string k public override DateTime GetDateTime(int i) { - DateTime dt = new DateTime(); - DateTime.TryParse(GetAttValue(i).S, out dt); + DateTime.TryParse(GetAttValue(i).S, null, DateTimeStyles.AdjustToUniversal, out DateTime dt); return dt; } @@ -325,42 +314,46 @@ private AttributeValue GetAttValue(int i) { return (AttributeValue)block.Item(pos, i); } - + private string GetAttValueN(int i) => GetAttValue(i)?.N ?? "0"; public override decimal GetDecimal(int i) { - return decimal.Parse(GetAttValue(i).N); + return decimal.Parse(GetAttValueN(i)); } - public override short GetInt16(int i) { - return short.Parse(GetAttValue(i).N); + return short.Parse(GetAttValueN(i)); } public override int GetInt32(int i) { - return int.Parse(GetAttValue(i).N); + return int.Parse(GetAttValueN(i)); } public override long GetInt64(int i) { - return long.Parse(GetAttValue(i).N); + return long.Parse(GetAttValueN(i)); } public override string GetString(int i) { - return GetAttValue(i).S; + return DynamoDBHelper.GetString(GetAttValue(i)); } public override bool GetBoolean(int i) { - return GetAttValue(i).IsBOOLSet; + AttributeValue value = GetAttValue(i); + return value.IsBOOLSet && value.BOOL; } public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) { - throw new NotImplementedException(); + MemoryStream ms = GetAttValue(i).B; + if (ms == null) + return 0; + ms.Seek(fieldOffset, SeekOrigin.Begin); + return ms.Read(buffer, bufferoffset, length); } } } diff --git a/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBDataStoreHelper.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBDataStoreHelper.cs new file mode 100644 index 000000000..0c3cb20b8 --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBDataStoreHelper.cs @@ -0,0 +1,109 @@ +using GeneXus.Data.Dynamo; +using GeneXus.Utils; +using System; +using System.Collections.Generic; + +namespace GeneXus.Data.NTier +{ + public class DynamoDBDataStoreHelper: DynServiceDataStoreHelperBase + { + + public DynamoQuery NewQuery() => new DynamoQuery(this); + public DynamoQuery NewScan() => new DynamoScan(this); + + public DynamoDBMap Map(string name) + { + return new DynamoDBMap(name); + } + + public object empty(GXType gxtype) + { + switch(gxtype) + { + case GXType.Number: + case GXType.Int16: + case GXType.Int32: + case GXType.Int64: return 0; + case GXType.Date: + case GXType.DateTime: + case GXType.DateTime2: return DateTimeUtil.NullDate(); + case GXType.Byte: + case GXType.NChar: + case GXType.NClob: + case GXType.NVarChar: + case GXType.Char: + case GXType.LongVarChar: + case GXType.Clob: + case GXType.VarChar: + case GXType.Raw: + case GXType.Blob: return string.Empty; + case GXType.Boolean: return false; + case GXType.Decimal: return 0f; + case GXType.NText: + case GXType.Text: + case GXType.Image: + case GXType.UniqueIdentifier: + case GXType.Xml: return string.Empty; + case GXType.Geography: + case GXType.Geopoint: + case GXType.Geoline: + case GXType.Geopolygon: return new Geospatial(); + case GXType.DateAsChar: return string.Empty; + case GXType.Undefined: + default: return null; + + } + } + } + + public static class DynamoFluentExtensions + { + public static Query OrderBy(this Query dynamoQuery, string index) + { + return (dynamoQuery as DynamoQuery)?.OrderBy(index); + } + public static Query SetKey(this Query dynamoQuery, string partitionKey) + { + return (dynamoQuery as DynamoQuery)?.SetKey(partitionKey); + } + public static Query KeyFilter(this Query dynamoQuery, string[] filters) + { + return (dynamoQuery as DynamoQuery)?.KeyFilter(filters); + } + } + + public class DynamoQuery : Query + { + public string Index { get; set; } + public bool ScanIndexForward = true; + private const string RANGE_KEY_INDEX = "RangeKey"; + private static readonly char[] indexTrimChars = new char[] { '(', ')' }; + + public DynamoQuery OrderBy(string index) + { + if(index.StartsWith("(", StringComparison.InvariantCulture)) + { + ScanIndexForward = false; + index = index.Trim(indexTrimChars); + } + if (index != RANGE_KEY_INDEX) + Index = index; + return this; + } + + public string PartitionKey { get; private set; } + public DynamoQuery SetKey(string partitionKey) + { + PartitionKey = partitionKey; + return this; + } + internal IEnumerable KeyFilters { get; set; } = Array.Empty(); + public DynamoQuery KeyFilter(string[] filters) + { + KeyFilters = filters; + return this; + } + + public DynamoQuery(DynamoDBDataStoreHelper dataStoreHelper) : base(dataStoreHelper) { } + } +} diff --git a/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBHelper.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBHelper.cs new file mode 100644 index 000000000..4aa4789ce --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBHelper.cs @@ -0,0 +1,153 @@ +using Amazon.DynamoDBv2.Model; +using GeneXus.Data.NTier; +using GeneXus.Utils; +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +#if NETCORE +using System.Threading; +using System.Threading.Tasks; +#endif + +namespace GeneXus.Data.Dynamo +{ + internal class DynamoDBHelper + { +#if NETCORE + private static readonly TaskFactory mTaskFactory = new + TaskFactory(CancellationToken.None, + TaskCreationOptions.None, + TaskContinuationOptions.None, + TaskScheduler.Default); + internal static TResult RunSync(Func> func) => mTaskFactory.StartNew>(func).Unwrap().GetAwaiter().GetResult(); +#endif + + internal static AttributeValue ToAttributeValue(VarValue var) + { + return ToAttributeValue(GxService.GXTypeToDbType(var.Type), var.Value); + } + + internal static void GXToDynamoQueryParameter(Dictionary dynParm, ServiceParameter parm) => AddAttributeValue($":{ parm.ParameterName }", dynParm, parm); + + internal static bool AddAttributeValue(string parmName, string fromName, Dictionary values, IDataParameterCollection parms, IEnumerable queryVars) + { + if(!AddAttributeValue(parmName, values, parms[fromName] as ServiceParameter)) + { + VarValue varValue = queryVars.FirstOrDefault(v => v.Name == $":{fromName}"); + if (varValue != null) + values[parmName] = DynamoDBHelper.ToAttributeValue(varValue); + return varValue != null; + } + return true; + } + + internal static bool AddAttributeValue(string parmName, Dictionary dynParm, ServiceParameter parm) + { + if (parm == null) + return false; + AttributeValue value = ToAttributeValue(parm.DbType, parm.Value); + if (value != null) + { + dynParm[parmName] = value; + return true; + } + return false; + } + + internal static AttributeValue ToAttributeValue(DbType dbType, Object value) + { + AttributeValue attValue; + switch (dbType) + { + case DbType.Binary: + if (value is byte[] valueArr) + { + attValue = new AttributeValue + { + B = new MemoryStream(valueArr) + }; + break; + } + else throw new ArgumentException("Required value not found"); + case DbType.Boolean: + case DbType.Byte: + attValue = new AttributeValue + { + BOOL = (bool)value + }; + break; + case DbType.Time: + case DbType.Date: + attValue = new AttributeValue + { + S = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc).ToString("yyyy-MM-dd") + }; + break; + case DbType.DateTime2: + case DbType.DateTime: + attValue = new AttributeValue + { + S = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc).ToString("yyyy-MM-ddTHH:mm:ssK") + }; + break; + + + case DbType.UInt16: + case DbType.UInt32: + case DbType.UInt64: + case DbType.VarNumeric: + case DbType.Decimal: + case DbType.Double: + case DbType.Int16: + case DbType.Int32: + case DbType.Int64: + attValue = new AttributeValue + { + N = value.ToString() + }; + break; + default: + string valueS = value.ToString().Replace("%", string.Empty); + attValue = new AttributeValue + { + S = valueS + }; + break; + } + return attValue; + } + + public static string GetString(AttributeValue attValue) + { + string value = attValue.S; + if (value != null) + return value; + else if (attValue.NS.Count > 0) + return SetToString(attValue.NS); + else if (attValue.SS.Count > 0) + return SetToString(attValue.SS); + else if (attValue.IsBOOLSet) + return $"{ attValue.BOOL }"; + else if (attValue.IsMSet) + return JSONHelper.Serialize(ConvertToDictionary(attValue.M), Encoding.UTF8); + else if (attValue.IsLSet) + return JSONHelper.Serialize>(attValue.L.Select(item => GetString(item)).ToList()); + return null; + } + + private static Dictionary ConvertToDictionary(Dictionary m) + { + Dictionary dict = new Dictionary(); + foreach (KeyValuePair keyValues in m) + { + dict.Add(keyValues.Key, GetString(keyValues.Value)); + } + return dict; + } + + private static string SetToString(List nS) => $"[ { string.Join(", ", nS) } ]"; + } +} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBMaps.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBMaps.cs similarity index 58% rename from dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBMaps.cs rename to dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBMaps.cs index 63497aaf9..4c01e9d14 100644 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBMaps.cs +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBMaps.cs @@ -2,30 +2,27 @@ using GeneXus.Data.NTier; using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace GeneXus.Data.Dynamo { public class DynamoDBMap : Map { - - public DynamoDBMap(string name): base(name) - { + internal bool NeedsAttributeMap { get; } + public DynamoDBMap(string name): base(RemoveSharp(name)) + { + NeedsAttributeMap = name.StartsWith("#", StringComparison.InvariantCulture); } + private static string RemoveSharp(string name) => name.StartsWith("#", StringComparison.InvariantCulture) ? name.Substring(1) : name; public override object GetValue(IOServiceContext context, RecordEntryRow currentEntry) { Dictionary values = ((DynamoDBRecordEntry)currentEntry).CurrentRow; - AttributeValue val = null; - values.TryGetValue(GetName(context), out val); + values.TryGetValue(GetName(context), out AttributeValue val); return val; } - public override void SetValue(IOServiceContext context, RecordEntryRow currentEntry, object value) + public override void SetValue(RecordEntryRow currentEntry, object value) { throw new NotImplementedException(); } diff --git a/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBRequestWrapper.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBRequestWrapper.cs new file mode 100644 index 000000000..220b42b50 --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBRequestWrapper.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using Amazon.DynamoDBv2; +using Amazon.DynamoDBv2.Model; +#if NETCORE +using GeneXus.Data.Dynamo; +#endif + +namespace GeneXus.Data.NTier.DynamoDB +{ + public class RequestWrapper + { + private readonly AmazonDynamoDBClient mDynamoDB; + private readonly AmazonDynamoDBRequest mReq; + + public RequestWrapper(AmazonDynamoDBClient mDynamoDB, AmazonDynamoDBRequest req) + { + this.mDynamoDB = mDynamoDB; + this.mReq = req; + } + + public ResponseWrapper Read() + { + return Read(null); + } + + public ResponseWrapper Read(Dictionary lastEvaluatedKey) + { + if (mReq is ScanRequest scanReq) + { + scanReq.ExclusiveStartKey = lastEvaluatedKey; +#if NETCORE + ScanResponse scanResponse = DynamoDBHelper.RunSync(() => mDynamoDB.ScanAsync(scanReq)); +#else + ScanResponse scanResponse = mDynamoDB.Scan(scanReq); +#endif + return new ResponseWrapper(scanResponse); + } + if (mReq is QueryRequest queryReq) + { + queryReq.ExclusiveStartKey = lastEvaluatedKey; +#if NETCORE + QueryResponse queryResponse = DynamoDBHelper.RunSync(() => mDynamoDB.QueryAsync(queryReq)); +#else + QueryResponse queryResponse = mDynamoDB.Query(queryReq); +#endif + return new ResponseWrapper(queryResponse); + } + throw new NotImplementedException(); + } + + internal void Close() + { + mDynamoDB.Dispose(); + } + } +} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBResponseWrapper.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBResponseWrapper.cs similarity index 89% rename from dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBResponseWrapper.cs rename to dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBResponseWrapper.cs index 59024cea7..1aacb128e 100644 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBResponseWrapper.cs +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBResponseWrapper.cs @@ -1,9 +1,5 @@ using Amazon.DynamoDBv2.Model; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace GeneXus.Data.NTier.DynamoDB { diff --git a/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBScan.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBScan.cs new file mode 100644 index 000000000..080802b72 --- /dev/null +++ b/dotnet/src/dotnetcommon/DynService.Dynamo/DynamoDBScan.cs @@ -0,0 +1,10 @@ +namespace GeneXus.Data.NTier +{ + public class DynamoScan : DynamoQuery + { + public DynamoScan(DynamoDBDataStoreHelper dataStoreHelper):base(dataStoreHelper) + { + + } + } +} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/Properties/AssemblyInfo.cs b/dotnet/src/dotnetcommon/DynService.Dynamo/Properties/AssemblyInfo.cs similarity index 100% rename from dotnet/src/dotnetframework/DynService.Dynamo/Properties/AssemblyInfo.cs rename to dotnet/src/dotnetcommon/DynService.Dynamo/Properties/AssemblyInfo.cs diff --git a/dotnet/src/dotnetcore/Artech.Genexus.SDAPI/Artech.Genexus.SDAPI.csproj b/dotnet/src/dotnetcore/Artech.Genexus.SDAPI/Artech.Genexus.SDAPI.csproj index 1ced452ef..619afea15 100644 --- a/dotnet/src/dotnetcore/Artech.Genexus.SDAPI/Artech.Genexus.SDAPI.csproj +++ b/dotnet/src/dotnetcore/Artech.Genexus.SDAPI/Artech.Genexus.SDAPI.csproj @@ -32,13 +32,6 @@ - - - - - - - False diff --git a/dotnet/src/dotnetcore/DynService/Dynamo/DynService.DynamoDB.csproj b/dotnet/src/dotnetcore/DynService/Dynamo/DynService.DynamoDB.csproj new file mode 100644 index 000000000..7756884cb --- /dev/null +++ b/dotnet/src/dotnetcore/DynService/Dynamo/DynService.DynamoDB.csproj @@ -0,0 +1,34 @@ + + + net5.0;net6.0 + NETCORE + GeneXus.Data.NTier + GeneXus.Data.DynService.DynamoDB + false + DynamoDB + GeneXus.DynService.DynamoDB + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj b/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj index 9e144b035..f8a211ee4 100644 --- a/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj +++ b/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj @@ -12,11 +12,11 @@ - + - + diff --git a/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj b/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj index e8479db8c..ff9c157b1 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj +++ b/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj @@ -11,6 +11,7 @@ + diff --git a/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXBCRestService.cs b/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXBCRestService.cs index 6bd915c16..e41b34bfb 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXBCRestService.cs +++ b/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXBCRestService.cs @@ -12,7 +12,7 @@ namespace GeneXus.Application { - public class GXBCRestService :GxRestWrapper + internal class GXBCRestService :GxRestWrapper { GxSilentTrnSdt _worker; private const string INSERT_OR_UPDATE_PARAMETER = "insertorupdate"; diff --git a/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXRouting.cs b/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXRouting.cs index 192d77fd2..ccaf7d06f 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXRouting.cs +++ b/dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXRouting.cs @@ -23,7 +23,7 @@ namespace GxClasses.Web.Middleware { - public class GXRouting : IGXRouting + internal class GXRouting : IGXRouting { static readonly ILog log = log4net.LogManager.GetLogger(typeof(IGXRouting)); diff --git a/dotnet/src/dotnetcore/GxClasses.Web/Properties/AssemblyInfo.cs b/dotnet/src/dotnetcore/GxClasses.Web/Properties/AssemblyInfo.cs index 9c1ad7a93..d4b839475 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/Properties/AssemblyInfo.cs +++ b/dotnet/src/dotnetcore/GxClasses.Web/Properties/AssemblyInfo.cs @@ -2,4 +2,6 @@ [assembly: InternalsVisibleTo("DotNetCoreUnitTest")] -[assembly: InternalsVisibleTo("GxNetCoreStartup")] \ No newline at end of file +[assembly: InternalsVisibleTo("GxNetCoreStartup")] +[assembly: InternalsVisibleTo("GeneXus.Deploy.AzureFunctions.Handlers")] +[assembly: InternalsVisibleTo("AzureFunctionsTest")] \ No newline at end of file diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index 58285ee69..1601425d3 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -53,6 +53,8 @@ + + diff --git a/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs b/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs index 21c4953f3..f6325cc29 100644 --- a/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs +++ b/dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs @@ -1,8 +1,10 @@ using System.Runtime.CompilerServices; - [assembly: InternalsVisibleTo("GxClasses.Web")] [assembly: InternalsVisibleTo("GxSearch")] [assembly: InternalsVisibleTo("GxNetCoreStartup")] +[assembly: InternalsVisibleTo("GeneXus.Deploy.AzureFunctions.Handlers")] +[assembly: InternalsVisibleTo("AzureFunctionsTest")] [assembly: InternalsVisibleTo("GXQueue")] -[assembly: InternalsVisibleTo("GXMessageBroker")] \ No newline at end of file +[assembly: InternalsVisibleTo("GXMessageBroker")] +[assembly: InternalsVisibleTo("DotNetCoreUnitTest")] diff --git a/dotnet/src/dotnetcore/GxDataInitialization/GXDataInitialization.csproj b/dotnet/src/dotnetcore/GxDataInitialization/GXDataInitialization.csproj index 4c5da499e..7c41acaec 100644 --- a/dotnet/src/dotnetcore/GxDataInitialization/GXDataInitialization.csproj +++ b/dotnet/src/dotnetcore/GxDataInitialization/GXDataInitialization.csproj @@ -16,12 +16,6 @@ - - - true - \content\net6.0\ - - diff --git a/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj b/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj index 4822c701d..9c81f3842 100644 --- a/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj +++ b/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj @@ -18,6 +18,7 @@ + diff --git a/dotnet/src/dotnetcore/GxMail/GxMail.csproj b/dotnet/src/dotnetcore/GxMail/GxMail.csproj index 42e76af3a..fbeb0ea93 100644 --- a/dotnet/src/dotnetcore/GxMail/GxMail.csproj +++ b/dotnet/src/dotnetcore/GxMail/GxMail.csproj @@ -72,7 +72,6 @@ - diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj b/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj index fe91a110e..27fbeb856 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj @@ -28,12 +28,6 @@ - - - true - \content\net6.0\ - - diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs index e87a150b0..ff9f16a7d 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs @@ -81,10 +81,11 @@ public static IApplicationBuilder UseGXHandlerFactory(this IApplicationBuilder b { return builder.UseMiddleware(basePath); } - public static IApplicationBuilder MapWebSocketManager(this IApplicationBuilder app, - PathString path) + public static IApplicationBuilder MapWebSocketManager(this IApplicationBuilder app, string basePath) { - return app.Map(path, (_app) => _app.UseMiddleware()); + return app + .Map($"{basePath}/gxwebsocket" , (_app) => _app.UseMiddleware()) + .Map($"{basePath}/gxwebsocket.svc", (_app) => _app.UseMiddleware()); //Compatibility reasons. Remove in the future. } } @@ -337,7 +338,7 @@ public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHos app.UseWebSockets(); string basePath = string.IsNullOrEmpty(VirtualPath) ? string.Empty : $"/{VirtualPath}"; Config.ScriptPath = basePath; - app.MapWebSocketManager($"{basePath}/gxwebsocket.svc"); + app.MapWebSocketManager(basePath); app.MapWhen( context => IsAspx(context, basePath), diff --git a/dotnet/src/dotnetcore/Projects/StoreManager/StoreManager.csproj b/dotnet/src/dotnetcore/Projects/StoreManager/StoreManager.csproj index 64d060418..fba3e8425 100644 --- a/dotnet/src/dotnetcore/Projects/StoreManager/StoreManager.csproj +++ b/dotnet/src/dotnetcore/Projects/StoreManager/StoreManager.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -26,14 +26,12 @@ - - - - 1.42.0.1766 - - - - + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAmazonSQS/AWSQueue.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAmazonSQS/AWSQueue.cs index 5fd3829c3..f0ed5882d 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAmazonSQS/AWSQueue.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAmazonSQS/AWSQueue.cs @@ -66,6 +66,27 @@ private void Initialize(GXService providerService) _isFIFO = _queueURL.EndsWith(".fifo"); } + + public override string GetName() + { + return Name; + } + public bool GetMessageFromException(Exception ex, SdtMessages_Message msg) + { + try + { + AmazonSQSException sqs_ex = (AmazonSQSException)ex; + msg.gxTpr_Id = sqs_ex.ErrorCode; + msg.gxTpr_Description = sqs_ex.Message; + return true; + } + catch (Exception) + { + return false; + } + } + + #region API methods public void Clear(out bool success) { try @@ -81,134 +102,32 @@ public void Clear(out bool success) } } - public MessageQueueResult DeleteMessage(string messageHandleId, out bool success) + public MessageQueueResult DeleteMessage(SimpleQueueMessage simpleQueueMessage, out bool success) { success = false; MessageQueueResult messageQueueResult = new MessageQueueResult(); - - List messageHandleIdToDelete = new List { messageHandleId }; - IList messageQueueResults = RemoveMessages(messageHandleIdToDelete, out bool operationOK); - if ((operationOK) && (messageQueueResults != null)) - { - messageQueueResult = messageQueueResults[0]; + Task task = Task.Run(async () => await DeleteQueueMessageAsync(simpleQueueMessage.MessageHandleId)); + DeleteMessageResponse deleteMessageResponse = task.Result; + if ((deleteMessageResponse != null) && ((deleteMessageResponse.HttpStatusCode == System.Net.HttpStatusCode.Accepted) || (deleteMessageResponse.HttpStatusCode == System.Net.HttpStatusCode.Created) || (deleteMessageResponse.HttpStatusCode == System.Net.HttpStatusCode.OK))) + { success = true; - } - return messageQueueResult; - } + SetupMessageQueueResult(simpleQueueMessage, MessageQueueResultStatus.Deleted); - public IList DeleteMessages(List messageHandleId, out bool success) - { - return RemoveMessages(messageHandleId, out success); - } - private IList RemoveMessages(List messageHandleId, out bool success) - { - IList messageQueueResults = new List(); - success = false; - try - { - Task task = Task.Run(async () => await DeleteQueueMessageBatchAsync(messageHandleId)); - - DeleteMessageBatchResponse deleteMessageBatchResponse = task.Result; - if (deleteMessageBatchResponse != null) - success = (deleteMessageBatchResponse.Failed.Count == 0); - - foreach (BatchResultErrorEntry entry in deleteMessageBatchResponse.Failed) - { - MessageQueueResult messageQueueResult = SetupMessageQueueResult(entry); - messageQueueResults.Add(messageQueueResult); - } - - foreach (DeleteMessageBatchResultEntry entry in deleteMessageBatchResponse.Successful) - { - MessageQueueResult messageQueueResult = SetupMessageQueueResult(entry); - messageQueueResults.Add(messageQueueResult); - } - - } - catch (AggregateException ae) - { - throw ae; } - return messageQueueResults; + return messageQueueResult; } public IList DeleteMessages(IList simpleQueueMessages, out bool success) { return RemoveMessages(simpleQueueMessages, out success); } - private IList RemoveMessages(IList simpleQueueMessages, out bool success) - { - IList messageQueueResults = new List(); - List messageHandleIds = new List(); - success = false; - try - { - foreach (SimpleQueueMessage simpleQueueMessage in simpleQueueMessages) - { - messageHandleIds.Add(simpleQueueMessage.MessageHandleId); - } - Task task = Task.Run(async () => await DeleteQueueMessageBatchAsync(messageHandleIds)); - - DeleteMessageBatchResponse deleteMessageBatchResponse = task.Result; - if (deleteMessageBatchResponse != null) - success = (deleteMessageBatchResponse.Failed.Count == 0); - - foreach (BatchResultErrorEntry entry in deleteMessageBatchResponse.Failed) - { - MessageQueueResult messageQueueResult = SetupMessageQueueResult(entry); - messageQueueResults.Add(messageQueueResult); - } - - foreach (DeleteMessageBatchResultEntry entry in deleteMessageBatchResponse.Successful) - { - MessageQueueResult messageQueueResult = SetupMessageQueueResult(entry); - messageQueueResults.Add(messageQueueResult); - } - - } - catch (AggregateException ae) - { - throw ae; - } - return messageQueueResults; - } - public IList GetMessages(out bool success) { return RetrieveMessages(success : out success); } - public IList GetMessages(MessageQueueOptions messageQueueOptions, out bool success) { return RetrieveMessages(out success, messageQueueOptions); } - private IList RetrieveMessages(out bool success, MessageQueueOptions messageQueueOptions = null) - { - success = false; - IList simpleQueueMessages = new List(); - try - { - Task task = Task.Run(async () => await GetMessageAsync(messageQueueOptions)); - - ReceiveMessageResponse response = task.Result; - success = response != null; - if (success) - { - List messagesList = response.Messages; - - foreach (Message message in messagesList) - { - SimpleQueueMessage simpleQueueMessage = SetupSimpleQueueMessage(message); - simpleQueueMessages.Add(simpleQueueMessage); - } - } - } - catch (AggregateException ae) - { - throw ae; - } - return simpleQueueMessages; - } - public int GetQueueLength(out bool success) { int approxNumberMessages = 0; @@ -231,7 +150,6 @@ public int GetQueueLength(out bool success) } return approxNumberMessages; } - public MessageQueueResult SendMessage(SimpleQueueMessage simpleQueueMessage, out bool success) { success = false; @@ -261,7 +179,6 @@ public MessageQueueResult SendMessage(SimpleQueueMessage simpleQueueMessage, out } return messageQueueResult; } - protected MessageQueueResult SendMessage(SimpleQueueMessage simpleQueueMessage, MessageQueueOptions messageQueueOptions, out bool success) { success = false; @@ -291,7 +208,6 @@ protected MessageQueueResult SendMessage(SimpleQueueMessage simpleQueueMessage, } return messageQueueResult; } - public IList SendMessages(IList simpleQueueMessages, MessageQueueOptions messageQueueOptions, out bool success) { success = false; @@ -322,26 +238,74 @@ public IList SendMessages(IList simpleQu } return messageQueueResults; } - - public override string GetName() + + private IList RemoveMessages(IList simpleQueueMessages, out bool success) { - return Name; + IList messageQueueResults = new List(); + List messageHandleIds = new List(); + success = false; + try + { + foreach (SimpleQueueMessage simpleQueueMessage in simpleQueueMessages) + { + messageHandleIds.Add(simpleQueueMessage.MessageHandleId); + } + Task task = Task.Run(async () => await DeleteQueueMessageBatchAsync(messageHandleIds)); + + DeleteMessageBatchResponse deleteMessageBatchResponse = task.Result; + if (deleteMessageBatchResponse != null) + success = (deleteMessageBatchResponse.Failed.Count == 0); + + foreach (BatchResultErrorEntry entry in deleteMessageBatchResponse.Failed) + { + MessageQueueResult messageQueueResult = SetupMessageQueueResult(entry); + messageQueueResults.Add(messageQueueResult); + } + + foreach (DeleteMessageBatchResultEntry entry in deleteMessageBatchResponse.Successful) + { + MessageQueueResult messageQueueResult = SetupMessageQueueResult(entry); + messageQueueResults.Add(messageQueueResult); + } + + } + catch (AggregateException ae) + { + throw ae; + } + return messageQueueResults; } - public bool GetMessageFromException(Exception ex, SdtMessages_Message msg) + private IList RetrieveMessages(out bool success, MessageQueueOptions messageQueueOptions = null) { + success = false; + IList simpleQueueMessages = new List(); try { - AmazonSQSException sqs_ex = (AmazonSQSException)ex; - msg.gxTpr_Id = sqs_ex.ErrorCode; - msg.gxTpr_Description = sqs_ex.Message; - return true; + Task task = Task.Run(async () => await GetMessageAsync(messageQueueOptions)); + + ReceiveMessageResponse response = task.Result; + success = response != null; + if (success) + { + List messagesList = response.Messages; + + foreach (Message message in messagesList) + { + SimpleQueueMessage simpleQueueMessage = SetupSimpleQueueMessage(message); + simpleQueueMessages.Add(simpleQueueMessage); + } + } } - catch (Exception) + catch (AggregateException ae) { - return false; + throw ae; } + return simpleQueueMessages; } + #endregion + + #region Transformation methods private MessageQueueResult SetupMessageQueueResult(SendMessageResponse response) { @@ -433,6 +397,19 @@ private SimpleQueueMessage SetupSimpleQueueMessage(Message response) return simpleQueueMessage; } + private MessageQueueResult SetupMessageQueueResult(SimpleQueueMessage simpleQueueMessage, string messageStatus) + { + MessageQueueResult messageQueueResult = new MessageQueueResult(); + messageQueueResult.MessageId = simpleQueueMessage.MessageId; + messageQueueResult.MessageStatus = messageStatus; + messageQueueResult.ServerMessageId = simpleQueueMessage.MessageId; + messageQueueResult.MessageHandleId = simpleQueueMessage.MessageHandleId; + return messageQueueResult; + } + + #endregion + + #region Async methods private async Task SendMessageAsync(SimpleQueueMessage simpleQueueMessage, MessageQueueOptions messageQueueOptions = null) { SendMessageResponse sendMessageResponse = new SendMessageResponse(); @@ -499,7 +476,11 @@ private async Task SendMessageBatchAsync(IList DeleteQueueMessageBatchAsync(List return deleteMessageBatchResponse; } + private async Task DeleteQueueMessageAsync(string messageHandleId) + { + DeleteMessageResponse deleteMessageResponse = new DeleteMessageResponse(); + try + { + + deleteMessageResponse = await _sqsClient.DeleteMessageAsync(_queueURL, messageHandleId).ConfigureAwait(false); + } + catch (Exception ex) + { + throw (ex); + } + return deleteMessageResponse; + } + private async Task PurgeQueueAsync() { PurgeQueueResponse purgeQueueResponse = new PurgeQueueResponse(); @@ -627,6 +623,8 @@ private async Task GetQueueAttributeAsync(List net6.0 + GeneXus.AWS.Queue + AWS SQS Queue Messaging - + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureMessageQueueProvider.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureMessageQueueProvider.cs index 9f6857498..698d7c0cc 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureMessageQueueProvider.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureMessageQueueProvider.cs @@ -7,8 +7,7 @@ public class AzureMessageQueueProvider { private const string AZUREQUEUE = "AZUREQUEUE"; public SimpleMessageQueue Connect(string queueName, string queueURL, out GXBaseCollection errorMessages, out bool success) - - { + { MessageQueueProvider messageQueueProvider = new MessageQueueProvider(); GXProperties properties = new GXProperties(); properties.Add("QUEUE_AZUREQUEUE_QUEUENAME", queueName); diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureQueue.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureQueue.cs index e18c42e7d..6953c8080 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureQueue.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/AzureQueue.cs @@ -83,7 +83,7 @@ public bool GetMessageFromException(Exception ex, SdtMessages_Message msg) /// Get the approximate number of messages in the queue /// /// - /// + /// int public int GetQueueLength(out bool success) { int cachedMessagesCount = 0; @@ -112,59 +112,38 @@ public void Clear(out bool success) } } - public MessageQueueResult DeleteMessage(string messageHandleId, out bool success) + /// + /// Delete a message. + /// + /// + /// + /// MessageQueueResult + public MessageQueueResult DeleteMessage(SimpleQueueMessage simpleQueueMessage, out bool success) { - //This method should receive messageHandleId + popReceipt success = false; MessageQueueResult messageQueueResult = new MessageQueueResult(); if (_queueClient is QueueClient && _queueClient.Exists()) { - Azure.Response receivedMessage = _queueClient.ReceiveMessage(); - - if ((receivedMessage != null) && (!receivedMessage.GetRawResponse().IsError) && (receivedMessage.Value != null) && (receivedMessage.Value.MessageId == messageHandleId)) + Azure.Response deleteResult = _queueClient.DeleteMessage(simpleQueueMessage?.MessageId, simpleQueueMessage?.MessageHandleId); + if (deleteResult != null) { - Azure.Response deleteResult = _queueClient.DeleteMessage(receivedMessage.Value.MessageId, receivedMessage.Value.PopReceipt); - - success = !deleteResult.IsError; - if (success) + if (!deleteResult.IsError) { - return (AzQueueMessageToMessageQueueResult(receivedMessage.Value, MessageQueueResultStatus.Deleted)); + messageQueueResult = SimpleQueueMessageToMessageQueueResult(simpleQueueMessage, MessageQueueResultStatus.Deleted); + success = true; } - } - } - return messageQueueResult; - } - - /// - /// Deletes permanently the messages given on the list. - /// - - public IList DeleteMessages(List messageHandleId, out bool success) - { - success = false; - IList messageQueueResults = new List(); - if (_queueClient is QueueClient && _queueClient.Exists()) - { - QueueMessage[] receivedMessages = _queueClient.ReceiveMessages(); - Azure.Response deleteResult; - foreach (QueueMessage message in receivedMessages) - { - if (messageHandleId.Contains(message.MessageId)) + else { - deleteResult = _queueClient.DeleteMessage(message?.MessageId, message?.PopReceipt); - if ((deleteResult != null) && (!deleteResult.IsError) && message is QueueMessage) - messageQueueResults.Add(AzQueueMessageToMessageQueueResult(queueMessage: message, status: MessageQueueResultStatus.Deleted)); + messageQueueResult = SimpleQueueMessageToMessageQueueResult(simpleQueueMessage, MessageQueueResultStatus.Failed); } } - success = true; } - return messageQueueResults; + return messageQueueResult; } /// /// Deletes permanently the messages given on the list. /// - public IList DeleteMessages(IList simpleQueueMessages, out bool success) { success = false; @@ -308,12 +287,11 @@ public MessageQueueResult SendMessage(SimpleQueueMessage simpleQueueMessage, out if ((sendReceipt != null) && (sendReceipt.Value != null)) { MessageQueueResult result = new MessageQueueResult() - { - MessageId = simpleQueueMessage.MessageId, + { + MessageId = sendReceipt.Value.MessageId, ServerMessageId = sendReceipt.Value.MessageId, MessageStatus = MessageQueueResultStatus.Sent, MessageAttributes = new GXProperties() - }; Type t = sendReceipt.Value.GetType(); PropertyInfo[] props = t.GetProperties(); diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj index 30e505229..a9fc132d3 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj @@ -2,10 +2,12 @@ net6.0 + GeneXus.Azure.Queue + Azure Queue Messaging - + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj index 4e7afff8d..b41e066ac 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/GXQueue.csproj @@ -2,7 +2,8 @@ net6.0 - TRACE;DEBUG;NETCORE + TRACE;DEBUG;NETCORE + GeneXus.Message.Queue diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/Queue.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/Queue.cs index c63399590..a3e118b3a 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/Queue.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/Queue.cs @@ -17,8 +17,7 @@ public interface IQueue IList SendMessages(IList simpleQueueMessages, MessageQueueOptions messageQueueOptions, out bool success); IList GetMessages(out bool success); IList GetMessages(MessageQueueOptions messageQueueOptions, out bool success); - MessageQueueResult DeleteMessage(string messageHandleId, out bool success); - IList DeleteMessages(List messageHandleId, out bool success); + MessageQueueResult DeleteMessage(SimpleQueueMessage simpleQueueMessage, out bool success); IList DeleteMessages(IList simpleQueueMessages, out bool success); void Clear(out bool success); bool GetMessageFromException(Exception ex, SdtMessages_Message msg); diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/SimpleMessageQueue.cs b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/SimpleMessageQueue.cs index c432357c0..e243ca161 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/SimpleMessageQueue.cs +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXQueue/SimpleMessageQueue.cs @@ -21,7 +21,7 @@ public class SimpleMessageQueue private const string SDT_MESSAGEPROPERTY_CLASS_NAME = @"SdtMessageProperty"; private const string SDT_MESSAGERESULT_CLASS_NAME = @"SdtMessageResult"; private const string NAMESPACE = @"GeneXus.Programs.genexusmessagingqueue.simplequeue"; - private const string GENEXUS_COMMON_DLL = @"GeneXus.Programs.Common.dll"; + private const string MODULE_DLL = @"GeneXusMessagingQueue"; public SimpleMessageQueue() { @@ -71,25 +71,27 @@ public int GetQueueLength(out GXBaseCollection errorMessage return queueLength; } - public GxUserType DeleteMessage(string messageHandleId, out GXBaseCollection errorMessages, out bool success) + public GxUserType DeleteMessage(GxUserType simpleQueueMessage, out GXBaseCollection errorMessages, out bool success) { + success = false; MessageQueueResult messageQueueResult = new MessageQueueResult(); - GxUserType messageResult = new GxUserType(); errorMessages = new GXBaseCollection(); try { - ValidQueue(); - messageQueueResult = queue.DeleteMessage(messageHandleId, out success); + ValidQueue(); + messageQueueResult = queue.DeleteMessage(TransformGXUserTypeToSimpleQueueMessage(simpleQueueMessage), out success); LoadAssemblyIfRequired(); try { if (messageQueueResult != null && TransformMessageQueueResult(messageQueueResult) is GxUserType result) + { + success = true; return result; + } } catch (Exception ex) { GXLogging.Error(logger, ex); - success = false; throw ex; } } @@ -97,48 +99,10 @@ public GxUserType DeleteMessage(string messageHandleId, out GXBaseCollection DeleteMessages(List messageHandleId, out GXBaseCollection errorMessages, out bool success) - { - IList messageQueueResults = new List(); - errorMessages = new GXBaseCollection(); - IList messageResults = new List(); - success = false; - try - { - try - { - ValidQueue(); - messageQueueResults = queue.DeleteMessages(messageHandleId, out success); - LoadAssemblyIfRequired(); - foreach (MessageQueueResult messageResult in messageQueueResults) - { - if (TransformMessageQueueResult(messageResult) is GxUserType result) - messageResults.Add(result); - } - success = true; - } - catch (Exception ex) - { - GXLogging.Error(logger, ex); - QueueErrorMessagesSetup(ex, out errorMessages); - success = false; - } - } - catch (Exception ex) - { - GXLogging.Error(logger, ex); - success = false; - throw ex; - } - - return messageResults; - } - public IList DeleteMessages(IList simpleQueueMessages, out GXBaseCollection errorMessages, out bool success) { IList messageQueueResults = new List(); @@ -264,9 +228,7 @@ private static void LoadAssemblyIfRequired() { if (assembly == null) { - assembly = LoadAssembly(Path.Combine(GxContext.StaticPhysicalPath(), GENEXUS_COMMON_DLL)); - if (assembly == null) - assembly = LoadAssembly(Path.Combine(GxContext.StaticPhysicalPath(), "bin", GENEXUS_COMMON_DLL)); + assembly = AssemblyLoader.LoadAssembly(new AssemblyName(MODULE_DLL)); } } @@ -362,16 +324,6 @@ private GxUserType TransformMessageQueueResult(MessageQueueResult messageQueueRe return messageResultSDT; } return null; - } - private static Assembly LoadAssembly(string fileName) - { - if (File.Exists(fileName)) - { - Assembly assemblyLoaded = Assembly.LoadFrom(fileName); - return assemblyLoaded; - } - else - return null; } public GxUserType SendMessage(GxUserType simpleQueueMessage, out GXBaseCollection errorMessages, out bool success) { diff --git a/dotnet/src/dotnetcore/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj b/dotnet/src/dotnetcore/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj index 927009f41..2f83482a0 100644 --- a/dotnet/src/dotnetcore/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj +++ b/dotnet/src/dotnetcore/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj @@ -12,7 +12,7 @@ - + diff --git a/dotnet/src/dotnetcore/Providers/Storage/GXGoogleCloudNetCore/GXGoogleCloudNetCore.csproj b/dotnet/src/dotnetcore/Providers/Storage/GXGoogleCloudNetCore/GXGoogleCloudNetCore.csproj index 1a17a13ff..f036cd022 100644 --- a/dotnet/src/dotnetcore/Providers/Storage/GXGoogleCloudNetCore/GXGoogleCloudNetCore.csproj +++ b/dotnet/src/dotnetcore/Providers/Storage/GXGoogleCloudNetCore/GXGoogleCloudNetCore.csproj @@ -14,8 +14,9 @@ - - + + + diff --git a/dotnet/src/dotnetcore/Reor/Reor.csproj b/dotnet/src/dotnetcore/Reor/Reor.csproj index c0a9951e4..f02fc7005 100644 --- a/dotnet/src/dotnetcore/Reor/Reor.csproj +++ b/dotnet/src/dotnetcore/Reor/Reor.csproj @@ -1,4 +1,4 @@ - + net6.0 Exe @@ -28,10 +28,4 @@ - - - true - \content\net6.0\ - - \ No newline at end of file diff --git a/dotnet/src/dotnetframework/DynService.Core/DynService.Core.csproj b/dotnet/src/dotnetframework/DynService.Core/DynService.Core.csproj deleted file mode 100644 index 72410d78f..000000000 --- a/dotnet/src/dotnetframework/DynService.Core/DynService.Core.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - net462 - GeneXus.Data.NTier - GeneXus.Data.DynService.Core - CA1812 - Dynservice - GeneXus.DynService.Core - - - - - \ No newline at end of file diff --git a/dotnet/src/dotnetframework/DynService.Core/GlobalSuppressions.cs b/dotnet/src/dotnetframework/DynService.Core/GlobalSuppressions.cs deleted file mode 100644 index 292ccd6ae..000000000 --- a/dotnet/src/dotnetframework/DynService.Core/GlobalSuppressions.cs +++ /dev/null @@ -1,12 +0,0 @@ -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. -// Project-level suppressions either have no target or are given -// a specific target and scoped to a namespace, type, member, etc. - -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.Query.AssignAtts")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.Query.Filters")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.Query.OrderBys")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.Query.Projection")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.Query.SelectList")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.Query.Vars")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "", Scope = "member", Target = "~P:GeneXus.Data.NTier.QueryExpression.Select")] diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynService.DynamoDB.csproj b/dotnet/src/dotnetframework/DynService.Dynamo/DynService.DynamoDB.csproj deleted file mode 100644 index 41d1c00ce..000000000 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynService.DynamoDB.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - net462 - GeneXus.Data.NTier - GeneXus.Data.DynService.DynamoDB - false - DynamoDB - GeneXus.DynService.DynamoDB - - - - - - - - - \ No newline at end of file diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBConnection.cs b/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBConnection.cs deleted file mode 100644 index 72247b237..000000000 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBConnection.cs +++ /dev/null @@ -1,226 +0,0 @@ -using Amazon; -using Amazon.DynamoDBv2; -using Amazon.DynamoDBv2.Model; -using Amazon.Runtime; -using GeneXus.Data.Dynamo; -using GeneXus.Data.NTier.DynamoDB; -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Text.RegularExpressions; -using System.Linq; -using GeneXus.Cache; - -namespace GeneXus.Data.NTier -{ - - public class DynamoDBService: GxService - { - public DynamoDBService(string id, string providerId): base(id, providerId, typeof(DynamoDBConnection)) - { - - } - - public override IDataReader GetCacheDataReader(CacheItem item, bool computeSize, string keyCache) - { - return new GxDynamoDBCacheDataReader(item, computeSize, keyCache); - } - } - - public class DynamoDBConnection : ServiceConnection - { - private readonly string CLIENT_ID = "User Id"; - private readonly string CLIENT_SECRET = "password"; - private readonly string REGION = "region"; - private AmazonDynamoDBClient mDynamoDB; - private AWSCredentials mCredentials; - private RegionEndpoint mRegion = RegionEndpoint.USEast1; - - public override string ConnectionString - { - get { return base.ConnectionString; } - - set - { - base.ConnectionString = value; - } - } - - private void InitializeDBConnection() - { - - DbConnectionStringBuilder builder = new DbConnectionStringBuilder(false); - builder.ConnectionString = this.ConnectionString; - if (builder.TryGetValue(CLIENT_ID, out object clientId) && builder.TryGetValue(CLIENT_SECRET, out object clientSecret)) - { - mCredentials = new BasicAWSCredentials(clientId.ToString(), clientSecret.ToString()); - } - if (builder.TryGetValue(REGION, out object region)) - { - mRegion = RegionEndpoint.GetBySystemName(region.ToString()); - } - } - private bool Initialize() - { - InitializeDBConnection(); - State = ConnectionState.Executing; - mDynamoDB = new Amazon.DynamoDBv2.AmazonDynamoDBClient(mCredentials, mRegion); - return true; - } - - public override int ExecuteNonQuery(ServiceCursorDef cursorDef, IDataParameterCollection parms, CommandBehavior behavior) - { - Initialize(); - Query query = cursorDef.Query as Query; - - Dictionary values = new Dictionary(); - if (parms.Count > 0) - { - for (int i = 0; i < parms.Count; i++) - { - ServiceParameter parm = parms[i] as ServiceParameter; - DynamoDBHelper.GXToDynamoQueryParameter("", values, parm); - } - } - var pattern = @"\((.*) = :(.*)\)"; - Dictionary keyCondition = new Dictionary(); - List filters = new List(); - - foreach (var keyFilter in query.Filters) - { - var match = Regex.Match(keyFilter, pattern); - String varName = match.Groups[2].Value; - if (match.Groups.Count > 1) - { - keyCondition[match.Groups[1].Value] = values[varName]; - } - } - AmazonDynamoDBRequest request = null; - - switch (query.CursorType) - { - case ServiceCursorDef.CursorType.Select: - throw new NotImplementedException(); - - case ServiceCursorDef.CursorType.Delete: - request = new DeleteItemRequest() - { - TableName = query.TableName, - Key = keyCondition - }; - mDynamoDB.DeleteItem((DeleteItemRequest)request); - - break; - case ServiceCursorDef.CursorType.Insert: - request = new PutItemRequest - { - TableName = query.TableName, - Item = values - }; - mDynamoDB.PutItem((PutItemRequest)request); - break; - case ServiceCursorDef.CursorType.Update: - request = new UpdateItemRequest - { - TableName = query.TableName, - Key = keyCondition, - AttributeUpdates = ToAttributeUpdates(keyCondition, values) - - }; - mDynamoDB.UpdateItem((UpdateItemRequest)request); - break; - - default: - break; - } - - return 0; - } - - private Dictionary ToAttributeUpdates(Dictionary keyConditions, Dictionary values) - { - Dictionary updates = new Dictionary(); - foreach (var item in values) - { - if (!keyConditions.ContainsKey(item.Key) && !item.Key.StartsWith("AV")) - { - updates[item.Key] = new AttributeValueUpdate(item.Value, AttributeAction.PUT); - } - } - return updates; - } - - public override IDataReader ExecuteReader(ServiceCursorDef cursorDef, IDataParameterCollection parms, CommandBehavior behavior) - { - - Initialize(); - Query query = cursorDef.Query as Query; - Dictionary valuesAux = new Dictionary(); - Dictionary values = new Dictionary(); - if (parms.Count > 0) - { - for (int i = 0; i < parms.Count; i++) - { - ServiceParameter parm = parms[i] as ServiceParameter; - DynamoDBHelper.GXToDynamoQueryParameter(":", values, parm); - } - } - - List filtersAux = new List(); - List filters = new List(); - - filters.AddRange(query.Filters); - - foreach (var item in query.Vars) - { - values.Add(item.Name, DynamoDBHelper.ToAttributeValue(item)); - } - - try - { - DynamoDBDataReader dataReader; - AmazonDynamoDBRequest req; - CreateDynamoQuery(query, values, filters.ToArray(), out dataReader, out req); - RequestWrapper reqWrapper = new RequestWrapper(mDynamoDB, req); - dataReader = new DynamoDBDataReader(cursorDef, reqWrapper, parms); - return dataReader; - } - catch (AmazonDynamoDBException e) { throw e; } - catch (AmazonServiceException e) { throw e; } - catch (Exception e) { throw e; } - } - - private static void CreateDynamoQuery(Query query, Dictionary values, String[] queryFilters, out DynamoDBDataReader dataReader, out AmazonDynamoDBRequest req) - { - dataReader = null; - req = null; - if (query is Scan) - { - req = new ScanRequest - { - TableName = query.TableName, - ProjectionExpression = String.Join(",", query.Projection), - - }; - if (queryFilters.Length > 0) - { - ((ScanRequest)req).FilterExpression = String.Join(" AND ", queryFilters); - ((ScanRequest)req).ExpressionAttributeValues = values; - } - } - else - { - req = new QueryRequest - { - TableName = query.TableName, - KeyConditionExpression = String.Join(" AND ", query.Filters), - ExpressionAttributeValues = values, - ProjectionExpression = String.Join(",", query.Projection), - - }; - } - } - - } -} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBDataStoreHelper.cs b/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBDataStoreHelper.cs deleted file mode 100644 index 86d97da9f..000000000 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBDataStoreHelper.cs +++ /dev/null @@ -1,20 +0,0 @@ -using GeneXus.Data.Dynamo; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace GeneXus.Data.NTier -{ - public class DynamoDBDataStoreHelper: DataStoreHelperBase - { - - public DynamoDBMap Map(string name) - { - return new DynamoDBMap(name); - } - } - - -} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBHelper.cs b/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBHelper.cs deleted file mode 100644 index 6a66c2fea..000000000 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBHelper.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Amazon.DynamoDBv2.Model; -using GeneXus.Data.NTier; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace GeneXus.Data.Dynamo -{ - internal class DynamoDBHelper - { - internal static AttributeValue ToAttributeValue(VarValue var) - { - return ToAttributeValue(GxService.GXTypeToDbType(var.Type), var.Value, false); - } - - internal static void GXToDynamoQueryParameter(string prefix, Dictionary dynParm, ServiceParameter parm) - { - AttributeValue v = ToAttributeValue(parm.DbType, parm.Value, true); - if (v != null) - dynParm[$"{prefix}{parm.ParameterName}"] = v; - } - - private static AttributeValue ToAttributeValue(DbType dbType, Object value, bool skipEmpty) - { - AttributeValue attValue = null; - switch (dbType) - { - case System.Data.DbType.Binary: - throw new NotImplementedException("Binary column not implemented yet"); - case System.Data.DbType.Boolean: - case System.Data.DbType.Byte: - attValue = new AttributeValue - { - BOOL = (bool)value - }; - break; - case System.Data.DbType.Time: - case System.Data.DbType.Date: - case System.Data.DbType.DateTime2: - case System.Data.DbType.DateTime: - attValue = new AttributeValue - { - S = value.ToString() - }; - break; - - - case System.Data.DbType.UInt16: - case System.Data.DbType.UInt32: - case System.Data.DbType.UInt64: - case System.Data.DbType.VarNumeric: - case System.Data.DbType.Decimal: - case System.Data.DbType.Double: - case System.Data.DbType.Int16: - case System.Data.DbType.Int32: - case System.Data.DbType.Int64: - attValue = new AttributeValue - { - N = value.ToString() - }; - break; - default: - //DynamoDB does not support empty values - string valueS = value.ToString().Replace("%", string.Empty); - if (!string.IsNullOrEmpty(valueS)) - { - attValue = new AttributeValue - { - S = valueS - }; - } - break; - } - return attValue; - } - } -} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBRequestWrapper.cs b/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBRequestWrapper.cs deleted file mode 100644 index d123627b5..000000000 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBRequestWrapper.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Amazon.DynamoDBv2; -using Amazon.DynamoDBv2.Model; - -namespace GeneXus.Data.NTier.DynamoDB -{ - public class RequestWrapper - { - private AmazonDynamoDBClient mDynamoDB; - private AmazonDynamoDBRequest mReq; - - public RequestWrapper() - { - - } - - public RequestWrapper(AmazonDynamoDBClient mDynamoDB, AmazonDynamoDBRequest req) - { - this.mDynamoDB = mDynamoDB; - this.mReq = req; - } - - public ResponseWrapper Read() - { - return Read(null); - } - - public ResponseWrapper Read(Dictionary lastEvaluatedKey) - { - if (mReq is ScanRequest) - { - ((ScanRequest)mReq).ExclusiveStartKey = lastEvaluatedKey; - return new ResponseWrapper(mDynamoDB.Scan((ScanRequest)mReq)); - } - if (mReq is QueryRequest) - { - ((QueryRequest)mReq).ExclusiveStartKey = lastEvaluatedKey; - return new ResponseWrapper(mDynamoDB.Query((QueryRequest)mReq)); - } - throw new NotImplementedException(); - } - - internal void Close() - { - mDynamoDB.Dispose(); - } - } -} diff --git a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBScan.cs b/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBScan.cs deleted file mode 100644 index 9c1442355..000000000 --- a/dotnet/src/dotnetframework/DynService.Dynamo/DynamoDBScan.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace GeneXus.Data.NTier -{ - public class Scan: Query - { - public Scan(object dataStoreHelper):base(dataStoreHelper) - { - - } - } -} diff --git a/dotnet/src/dotnetframework/DynServiceFabric/DynService.Fabric.csproj b/dotnet/src/dotnetframework/DynServiceFabric/DynService.Fabric.csproj index cce2c76e6..ea8f1ae6a 100644 --- a/dotnet/src/dotnetframework/DynServiceFabric/DynService.Fabric.csproj +++ b/dotnet/src/dotnetframework/DynServiceFabric/DynService.Fabric.csproj @@ -1,4 +1,4 @@ - + net462 GeneXus.Data.DynService.Fabric @@ -12,13 +12,13 @@ - + - + diff --git a/dotnet/src/dotnetframework/DynServiceFabric/FabricDataReader.cs b/dotnet/src/dotnetframework/DynServiceFabric/FabricDataReader.cs index ebf7c4360..6025ad3e3 100644 --- a/dotnet/src/dotnetframework/DynServiceFabric/FabricDataReader.cs +++ b/dotnet/src/dotnetframework/DynServiceFabric/FabricDataReader.cs @@ -232,7 +232,7 @@ public int GetValues(object[] values) { System.Diagnostics.Debug.Assert(mResponse[mCurrentPosition].Values.Count == values.Length, "Values mismatch"); int i = 0; - foreach (var attName in mProjection) + foreach (string attName in mProjection) { values[i] = mResponse[mCurrentPosition][attName]; i++; diff --git a/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj b/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj index 906d0183c..7ef6d238e 100644 --- a/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj +++ b/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj @@ -10,7 +10,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/ConnectionBuilder.cs b/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/ConnectionBuilder.cs index 6cecd261c..710a1fa2f 100644 --- a/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/ConnectionBuilder.cs +++ b/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/ConnectionBuilder.cs @@ -3,7 +3,7 @@ using System.Collections; using System.ComponentModel; using System.Windows.Forms; -using System.Data; +using System.Data.SqlClient; using System.Diagnostics; using System.Collections.Generic; using Genexus.RegistryUtilities; @@ -434,7 +434,8 @@ bool TestConnection(out string sMessage) { try { - connectionTest = new System.Data.OleDb.OleDbConnection(ConnectionString); + SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder(ConnectionString); + connectionTest = new System.Data.OleDb.OleDbConnection(sqlConnectionStringBuilder.ConnectionString); connectionTest.Open(); sMessage = ""; return true; @@ -609,10 +610,12 @@ public bool PersistSecurityInfo } + public string ConnectionString { get { + string sConn = String.Format("Provider={0};Persist Security Info={1};{2};Initial Catalog={3};Data Source={4};", "SQLOLEDB.1", PersistSecurityInfo.ToString(), UserAndPassword, Database, Server); return sConn; diff --git a/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/OracleConnectionBuilder.cs b/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/OracleConnectionBuilder.cs index 25508b6af..1e72dfa26 100644 --- a/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/OracleConnectionBuilder.cs +++ b/dotnet/src/dotnetframework/GxClasses.Win/ConnectionDialog/OracleConnectionBuilder.cs @@ -5,6 +5,7 @@ using System.Windows.Forms; using System.Data; using System.Diagnostics; +using System.Data.SqlClient; namespace ConnectionBuilder { @@ -304,7 +305,8 @@ private void testConnection_Click(object sender, System.EventArgs e) { try { - connectionTest = new System.Data.OleDb.OleDbConnection(ConnectionString); + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(ConnectionString); + connectionTest = new System.Data.OleDb.OleDbConnection(builder.ConnectionString); connectionTest.Open(); connectionTest.Close(); } diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs index 96b8eccf2..f5ab562f3 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs @@ -44,6 +44,7 @@ namespace GeneXus.Application #endif using System.Threading; using System.Security.Claims; + using System.Security; public interface IGxContext { @@ -74,7 +75,7 @@ public interface IGxContext GxHttpContextVars httpContextVars { get; set; } T ReadSessionKey(string key) where T : class; bool WriteSessionKey(string key, T value) where T : class; - + List userStyleSheetFiles { get; } void DoAfterInit(); void PushCurrentUrl(); bool isSmartDevice(); @@ -314,6 +315,7 @@ public class GxContext : IGxContext internal static string GX_SPA_REDIRECT_URL = "X-SPA-REDIRECT-URL"; internal const string GXLanguage = "GXLanguage"; internal const string GXTheme = "GXTheme"; + internal const string SERVER_VAR_HTTP_HOST = "HTTP_HOST"; [NonSerialized] HttpContext _HttpContext; [NonSerialized] @@ -325,6 +327,11 @@ public class GxContext : IGxContext GxXmlContext _XMLContext; [NonSerialized] GxErrorHandlerInfo _errorHandlerInfo; + [NonSerialized] + private List _userStyleSheetFiles = new List(); + public List userStyleSheetFiles { + get { return _userStyleSheetFiles; } + } string _gxUserId; string _clientId = string.Empty; string _gxPasswrd; @@ -1550,7 +1557,9 @@ static public string StdClassesVersion() public MessageQueueTransaction MQTransaction { + [SecuritySafeCritical] get { return _mqTransaction; } + [SecuritySafeCritical] set { _mqTransaction = value; @@ -1708,10 +1717,7 @@ public bool WriteSessionKey(string key, T value) where T : class #if !NETCORE HttpContext.Session[key] = value; #else - if (!_HttpContext.Response.HasStarted) - { - HttpContext.Session.SetString(key, (value != null ? JSONHelper.Serialize(value) : string.Empty)); - } + HttpContext.Session.SetString(key, (value != null ? JSONHelper.Serialize(value) : string.Empty)); #endif return true; } @@ -2756,7 +2762,9 @@ public virtual string GetServerName() if (Config.GetValueOf("SERVER_NAME", out serverName)) return serverName; #if !NETCORE - serverName = _HttpContext.Request.ServerVariables["http_host"]; + serverName = _HttpContext.Request.ServerVariables[SERVER_VAR_HTTP_HOST]; +#else + serverName = _HttpContext.GetServerVariable(SERVER_VAR_HTTP_HOST); #endif if (String.IsNullOrEmpty(serverName)) { @@ -2768,9 +2776,8 @@ public virtual string GetServerName() return serverName; } catch - { - return ""; + return string.Empty; } } private static bool DynamicPortRequest(HttpRequest request) diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs index 1cc07c9fe..0a8c1687b 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs @@ -45,6 +45,7 @@ using System.Security; using System.Threading.Tasks; using System.Drawing.Imaging; +using System.Net.Http.Headers; namespace GeneXus.Utils { @@ -1586,7 +1587,7 @@ public static string JSONEncode(string s) { char ch = s[index]; - if ((ch == '\\') || (ch == '"') || (ch == '>')) + if ((ch == '\\') || (ch == '"')) { sb.Append('\\'); sb.Append(ch); @@ -2297,6 +2298,20 @@ static string FormatEmptyDate(string pic) } return emptyDT.ToString(); } + static string FormatEmptyJsonDate(string pic) + { + StringBuilder emptyDT = new StringBuilder(pic); + emptyDT.Replace('d', '0'); + emptyDT.Replace('M', '0'); + emptyDT.Replace('y', '0'); + + emptyDT.Replace('m', '0'); + emptyDT.Replace('s', '0'); + emptyDT.Replace('f', '0'); + emptyDT.Replace('h', '0'); + emptyDT.Replace('H', '0'); + return emptyDT.ToString(); + } string TimeFormatFromSDT(String S, String TSep, bool allowsOneDigitTime) { int pos1, pos2, pos3, tSize, ampmFmt; @@ -2551,6 +2566,13 @@ public static string DToC2(DateTime dt) else return dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); } + internal static string DToC2(DateTime dt, string format) + { + if (dt == nullDate) + return FormatEmptyJsonDate(format); + else + return dt.ToString(format, CultureInfo.InvariantCulture); + } public static DateTime CToD2(string value) { if (isNullJsonDate(value)) @@ -4175,6 +4197,40 @@ internal static string AttributeEncode(string sText) return HttpUtility.HtmlAttributeEncode(sText); } + internal static string EncodeContentDispositionHeader(string value, int browserType) + { + int filenameIdx = value.IndexOf("filename", StringComparison.OrdinalIgnoreCase); + int eqIdx = value.IndexOf("=", filenameIdx); + if (filenameIdx == -1 || eqIdx == -1 || browserType == GxContext.BROWSER_SAFARI) //Safari does not supports yet ContentDispositon file name encoding value. + { + return value; + } + + string rawFilename = value.Substring(eqIdx + 1).Trim(); + try + { + string dispositionType = value.Substring(0, value.IndexOf(";")).Trim(); + value = new ContentDispositionHeaderValue(dispositionType) { FileName = rawFilename }.ToString(); + } + catch (Exception) + { + value = value.Substring(0, eqIdx + 1) + EncodeContentDispositionFileName(rawFilename); + } + return value; + } + + private static string EncodeContentDispositionFileName(string filename) + { + try + { + return Uri.EscapeDataString(filename); + } + catch (UriFormatException) //Contains High Surrogate Chars + { + return GXUtil.UrlEncode(filename); + } + } + public static string HtmlEndTag(HTMLElement element) { if ((Preferences.DocType == HTMLDocType.HTML4 || Preferences.DocType == HTMLDocType.NONE || Preferences.DocType == HTMLDocType.HTML4S) && diff --git a/dotnet/src/dotnetframework/GxClasses/Core/Web/GxHttpServer.cs b/dotnet/src/dotnetframework/GxClasses/Core/Web/GxHttpServer.cs index 14d4b2e10..e6b368e37 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/Web/GxHttpServer.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/Web/GxHttpServer.cs @@ -11,6 +11,12 @@ namespace GeneXus.Http.Server using Microsoft.AspNetCore.Http.Extensions; using System.Linq; using Microsoft.AspNetCore.Http.Features; + using System.Text; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc.Formatters; + using System.Net.Http; + using Stubble.Core.Contexts; + using System.Net.Mime; #endif public class GxHttpCookie @@ -64,6 +70,8 @@ public DateTime ExpirationDate get { return _ExpirationDate; } } + public string SameSite { get; set; } + public String Domain { set { _Domain = value; } @@ -143,32 +151,12 @@ public void AppendHeader( string name, string value) { if(string.Compare(name, "Content-Disposition", true) == 0) { - value = GetEncodedContentDisposition(value); + value = GXUtil.EncodeContentDispositionHeader(value, _context.GetBrowserType()); } if (_context!=null) _context.SetHeader(name, value); } - private string GetEncodedContentDisposition(string value) - { - int filenameIdx = value.ToLower().IndexOf("filename"); - if(filenameIdx != -1) - { - int eqIdx = value.ToLower().IndexOf("=", filenameIdx); - if (eqIdx != -1) - { - string filename = value.Substring(eqIdx + 1).Trim(); - try - { - value = value.Substring(0, eqIdx + 1) + Uri.EscapeDataString(filename); - } - catch(UriFormatException) //Contains High Surrogate Chars - { - value = value.Substring(0, eqIdx + 1) + GXUtil.UrlEncode(filename); - } - } - } - return value; - } + } public class GxSoapRequest : GxHttpRequest @@ -391,11 +379,14 @@ public string GetValue( string name) public override string ToString() { if (_httpReq == null) - return ""; + return String.Empty; #if NETCORE - return (new StreamReader(_httpReq.Body)).ReadToEnd(); + return _httpReq.GetRawBodyString(); #else - return (new StreamReader(_httpReq.InputStream)).ReadToEnd(); + using (StreamReader reader = new StreamReader(_httpReq.InputStream)) + { + return reader.ReadToEnd(); + } #endif } public void ToFile(string FileName) diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs index f593de63c..79d2d3cce 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs @@ -586,7 +586,7 @@ public void SetParameterMultimedia(int id, string parm, string multimediaParm) //Second execution of Dataprovider that updates images, CategoryImage = calendar.Link(), image_gxi=https://chatteatest.s3.amazonaws.com/TestPGXReleased/Category/CategoryImage/calendar_dc0ca2d9335a484cbdc2d21fc7568af7.png, copy falla, multimediaUri = image_gxi; #pragma warning disable SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}' public void SetParameterMultimedia(int id, string image_gxi, string image, string tableName, string fieldName) -{ + { GXLogging.Debug(log, "SetParameterMultimedia image_gxi:", image_gxi + " image:" + image); bool storageServiceEnabled = !string.IsNullOrEmpty(tableName) && !string.IsNullOrEmpty(fieldName) && (GXServices.Instance != null && GXServices.Instance.Get(GXServices.STORAGE_SERVICE) != null); string imageUploadName=image; diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierService.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierService.cs index b8a1ff5d5..4df83cb39 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierService.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierService.cs @@ -186,6 +186,8 @@ public static DbType GXTypeToDbType(GXType type) return DbType.Object; case GXType.Blob: return DbType.Binary; + case GXType.Boolean: + return DbType.Boolean; case GXType.Undefined: default: return DbType.Object; diff --git a/dotnet/src/dotnetframework/GxClasses/Domain/GxHttpClient.cs b/dotnet/src/dotnetframework/GxClasses/Domain/GxHttpClient.cs index 4f3ea23a9..db488e0d6 100644 --- a/dotnet/src/dotnetframework/GxClasses/Domain/GxHttpClient.cs +++ b/dotnet/src/dotnetframework/GxClasses/Domain/GxHttpClient.cs @@ -606,7 +606,7 @@ void setHttpVersion(HttpRequestMessage req) [SecuritySafeCritical] HttpResponseMessage ExecuteRequest(string method, string requestUrl, CookieContainer cookies) { - GXLogging.Debug(log, String.Format("Start NetCore HTTPClient buildRequest: requestUrl:{0} method:{1}", requestUrl, method)); + GXLogging.Debug(log, String.Format("Start HTTPClient buildRequest: requestUrl:{0} method:{1}", requestUrl, method)); HttpRequestMessage request; HttpClient client; int BytesRead; @@ -767,7 +767,7 @@ public void HttpClientExecute(string method, string name) else _errDescription = aex.Message; response = new HttpResponseMessage(); - response.Content = new StringContent(_errDescription); + response.Content = new StringContent(HttpHelper.StatusCodeToTitle(HttpStatusCode.InternalServerError)); response.StatusCode = HttpStatusCode.InternalServerError; } #endif @@ -780,7 +780,7 @@ public void HttpClientExecute(string method, string name) else _errDescription = e.Message; response = new HttpResponseMessage(); - response.Content = new StringContent(_errDescription); + response.Content = new StringContent(HttpHelper.StatusCodeToTitle(HttpStatusCode.InternalServerError)); #if NETCORE response.StatusCode = (HttpStatusCode)(e.StatusCode != null ? e.StatusCode : HttpStatusCode.InternalServerError); #else @@ -794,7 +794,7 @@ public void HttpClientExecute(string method, string name) _errDescription = "The request has timed out. " + e.Message; response = new HttpResponseMessage(); response.StatusCode = 0; - response.Content = new StringContent(""); + response.Content = new StringContent(String.Empty); } catch (Exception e) { @@ -805,7 +805,7 @@ public void HttpClientExecute(string method, string name) else _errDescription = e.Message; response = new HttpResponseMessage(); - response.Content = new StringContent(_errDescription); + response.Content = new StringContent(HttpHelper.StatusCodeToTitle(HttpStatusCode.InternalServerError)); response.StatusCode = HttpStatusCode.InternalServerError; } GXLogging.Debug(log, "Reading response..."); diff --git a/dotnet/src/dotnetframework/GxClasses/Helpers/GXLogging.cs b/dotnet/src/dotnetframework/GxClasses/Helpers/GXLogging.cs index 4c20ae00c..e77d5ea1f 100644 --- a/dotnet/src/dotnetframework/GxClasses/Helpers/GXLogging.cs +++ b/dotnet/src/dotnetframework/GxClasses/Helpers/GXLogging.cs @@ -25,10 +25,7 @@ public static void Error(ILog log, string msg, Exception ex) } public static void Error(ILog log, string msg1, string msg2, Exception ex) { - if (log.IsErrorEnabled) - { - log.Error(msg1 + msg2, ex); - } + Error(log, msg1 + msg2, ex); } public static void Error(ILog log, Exception ex, params string[] list) { @@ -98,10 +95,7 @@ public static void Debug(ILog log, string startMsg, Func buildMsg) } public static void Debug(ILog log, string msg1, string msg2, Exception ex) { - if (log.IsDebugEnabled) - { - log.Debug(msg1 + msg2, ex); - } + Debug(log, msg1 + msg2, ex); } public static void Debug(ILog log, string msg, Exception ex) { diff --git a/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestAPIClient.cs b/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestAPIClient.cs new file mode 100644 index 000000000..a5d9b0a4f --- /dev/null +++ b/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestAPIClient.cs @@ -0,0 +1,361 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GeneXus.Utils; +using GeneXus.Http.Client; +using System.Web; +using GeneXus.Mime; +#if NETCORE +using System.Text.Json; +using System.Text.Json.Serialization; +#endif +using System.IO; + +namespace GeneXus.Application +{ + public class GXRestAPIClient + { + + public GXRestAPIClient() + { + Location = new GxLocation(); + Location.BaseUrl = "api"; + Location.Host = "www.example.com"; + Location.ResourceName = "service"; + Location.Port = 80; + } + + + private GxHttpClient httpClient = new GxHttpClient(); + public GxLocation Location { get; set; } + public string Name { get; set; } + public int ErrorCode { get; set; } + public string ErrorMessage { get; set; } + + public int StatusCode { get; set; } + + public int ResponseCode { get => responseCode; set => responseCode = value; } + public string ResponseMessage { get => responseMessage; set => responseMessage = value; } + public string HttpMethod { get => httpMethod; set => httpMethod = value; } + + public string protocol = "REST"; + + private string httpMethod = "GET"; + + private Dictionary _queryVars = new Dictionary(); + private Dictionary _bodyVars = new Dictionary(); + //private Dictionary _pathVars = new Dictionary(); + private Dictionary _responseData = new Dictionary(); + + private string _contentType = "application/json; charset=utf-8"; + private string _queryString = String.Empty; + private string _bodyString = String.Empty; + + private int responseCode = 0; + private string responseMessage = String.Empty; + + public void AddQueryVar(String varName, String varValue) + { + _queryVars[varName] = GXUtil.UrlEncode(varValue); + } + + public void AddQueryVar(String varName, int varValue) + { + _queryVars[varName] = varValue.ToString(); + } + public void AddQueryVar(String varName, short varValue) + { + _queryVars[varName] = varValue.ToString(); + } + + public void AddQueryVar(String varName, Decimal varValue) + { + _queryVars[varName] = varValue.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + + public void AddQueryVar(String varName, DateTime varValue) + { + _queryVars[varName] = varValue.ToString("yyyy-MM-dd"); + } + + public void AddQueryVar(String varName, DateTime varValue, bool hasMilliseconds) + { + string fmt = "yyyy-MM-ddTHH:mm:ss"; + if (hasMilliseconds) + fmt = "yyyy-MM-ddTHH:mm:ss.fff"; + _queryVars[varName] = varValue.ToString(fmt); + } + public void AddQueryVar(String varName, Guid varValue) + { + _queryVars[varName] = varValue.ToString(); + } + + public void AddQueryVar(String varName, Geospatial varValue) + { + _queryVars[varName] = GXUtil.UrlEncode(varValue.ToString()); + } + + public void AddQueryVar(String varName, bool varValue) + { + _queryVars[varName] = varValue.ToString(); + } + + public void AddQueryVar(String varName, GxUserType varValue) + { + if (varValue != null) + { + _bodyVars[varName] = varValue.ToJSonString(); + } + } + + public void AddQueryVar(String varName, IGxCollection varValue) + { + if (varValue != null) + { + _bodyVars[varName] = varValue.ToJSonString(); + } + } + + public void AddBodyVar(String varName, DateTime varValue) + { + _bodyVars[varName] = "\"" + varValue.ToString("yyyy-MM-dd") + "\""; + } + + public void AddBodyVar(String varName, DateTime varValue, bool hasMilliseconds) + { + string fmt = "yyyy-MM-ddTHH:mm:ss"; + if (hasMilliseconds) + fmt = "yyyy-MM-ddTHH:mm:ss.fff"; + _bodyVars[varName] = "\"" + varValue.ToString(fmt) + "\""; + } + + public void AddBodyVar(String varName, Decimal varValue) + { + _bodyVars[varName] = varValue.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + + public void AddBodyVar(String varName, string varValue) + { + _bodyVars[varName] = "\"" + varValue + "\"" ; + } + public void AddBodyVar(String varName, int varValue) + { + _bodyVars[varName] = varValue.ToString(); + } + public void AddBodyVar(String varName, short varValue) + { + _bodyVars[varName] = varValue.ToString(); + } + + public void AddBodyVar(String varName, bool varValue) + { + _bodyVars[varName] = varValue.ToString(); + } + public void AddBodyVar(String varName, Guid varValue) + { + _bodyVars[varName] = "\"" + varValue.ToString() + "\""; + } + + public void AddBodyVar(String varName, Geospatial varValue) + { + _bodyVars[varName] = "\"" + varValue.ToString() + "\""; + } + + public void AddBodyVar(String varName, GxUserType varValue) + { + if (varValue != null) + { + _bodyVars[varName] = varValue.ToJSonString(); + } + } + + public void AddBodyVar(String varName, IGxCollection varValue) + { + if (varValue != null) + { + _bodyVars[varName] = varValue.ToJSonString(); + } + } + + public string GetBodyString(string varName) + { + return GetJsonStr(varName); + } + + public DateTime GetBodyDate(string varName) + { + return DateTime.ParseExact(GetJsonStr(varName), "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); + } + + public DateTime GetBodyDateTime(string varName, bool hasMilliseconds) + { + string fmt = "yyyy-MM-ddTHH:mm:ss"; + if (hasMilliseconds) + fmt += ".fff"; + return DateTime.ParseExact(GetJsonStr(varName), fmt,System.Globalization.CultureInfo.InvariantCulture); + } + + public bool GetBodyBool(string varName) + { + return Boolean.Parse(GetJsonStr(varName)); + } + public Guid GetBodyGuid(string varName) + { + return Guid.Parse(GetJsonStr(varName)); + } + + public Decimal GetBodyNum(string varName) + { + return Decimal.Parse( GetJsonStr(varName)); + } + + public int GetBodyInt(string varName) + { + return Int32.Parse(GetJsonStr(varName)); + } + + public short GetBodyShort(string varName) + { + return (short)Int16.Parse(GetJsonStr(varName)); + } + public Geospatial GetBodyGeospatial(string varName) + { + Geospatial g = new Geospatial(GetJsonStr(varName)); + if (Geospatial.IsNullOrEmpty(g)) + { + g.FromGeoJSON(GetJsonStr(varName)); + } + return g; + } + + public string GetJsonStr(string varName) + { + string s = String.Empty; + if (_responseData.ContainsKey(varName.ToLower())) + { + s = _responseData[varName.ToLower()].ToString(); + } + else if (_responseData.Count == 1 && _responseData.ContainsKey(String.Empty)) + { + s = _responseData[String.Empty].ToString(); + } + return s; + } + + public T GetBodySdt(string varName) where T:GxUserType, new() + { + T sdt = new T(); + if (_responseData.ContainsKey(varName.ToLower())) + { + sdt.FromJSonString(_responseData[varName.ToLower()].ToString(), null); + } + else if (_responseData.Count == 1 && _responseData.ContainsKey(String.Empty)) + { + sdt.FromJSonString(_responseData[String.Empty].ToString(), null); + } + else if (_responseData.Count >= 1 && !_responseData.ContainsKey(varName.ToLower())) + { +#if NETCORE + sdt.FromJSonString(JsonSerializer.Serialize(_responseData), null); +#else + sdt.FromJSonString(JSONHelper.Serialize(_responseData), null); +#endif + } + return sdt; + } + + public GXBaseCollection GetBodySdtCollection(string varName) where T:GxUserType , new() + { + GXBaseCollection collection = new GXBaseCollection(); + if (_responseData.ContainsKey(varName.ToLower())) + { + collection.FromJSonString(_responseData[varName.ToLower()].ToString(), null); + } + else if (_responseData.Count == 1 && _responseData.ContainsKey(String.Empty)) + { + collection.FromJSonString(_responseData[String.Empty].ToString(), null); + } + return collection; + } + + public GxSimpleCollection GetBodySimpleCollection(string varName) + { + GxSimpleCollection collection = new GxSimpleCollection(); + if (_responseData.ContainsKey(varName.ToLower())) + { + collection.FromJSonString(_responseData[varName.ToLower()].ToString(), null); + } + else if (_responseData.Count == 1 && _responseData.ContainsKey(String.Empty)) + { + collection.FromJSonString(_responseData[String.Empty].ToString(), null); + } + return collection; + } + + public void AddUploadFile(string FilePath, string name) + { + httpClient.AddFile(FilePath, name); + string mimeType = MimeMapping.GetMimeMapping(FilePath); + _contentType = mimeType; + } + + public void RestExecute() + { + this.ErrorCode = 0; + _queryString = String.Empty; + if (_queryVars.Count > 0) + { + string separator = "?"; + foreach (string key in _queryVars.Keys) + { + _queryString += string.Format("{0}{1}={2}", separator, key, _queryVars[key]); + separator = "&"; + } + } + _bodyString = String.Empty; + if (_bodyVars.Count > 0) + { + string separator = String.Empty; + foreach (string key in _bodyVars.Keys) + { + _bodyString += separator + "\"" + key + "\":" + _bodyVars[key]; + separator = ","; + } + } + if (_bodyString.Length > 0) + { + _bodyString = "{" + _bodyString + "}"; + httpClient.AddString(_bodyString); + httpClient.AddHeader("Content-Type", _contentType); + } + else + { + if (this.httpMethod == "POST" || this.httpMethod == "PUT") + { + _bodyString = "{}"; + httpClient.AddString(_bodyString); + httpClient.AddHeader("Content-Type", _contentType); + } + } + string serviceuri = ((this.Location.Secure > 0) ? "https" : "http") + "://" + this.Location.Host; + serviceuri += (this.Location.Port != 80) ? ":" + this.Location.Port.ToString() : String.Empty; + serviceuri += "/" + this.Location.BaseUrl.TrimEnd('/').TrimStart('/') + "/" + this.Location.ResourceName; + serviceuri += _queryString; + httpClient.HttpClientExecute( this.HttpMethod, serviceuri); + if (httpClient.StatusCode >= 300 || httpClient.ErrCode > 0) + { + this.ErrorCode = (httpClient.ErrCode == 0)? 1: httpClient.ErrCode; + this.ErrorMessage = httpClient.ErrDescription; + this.StatusCode = httpClient.StatusCode; + _responseData = new Dictionary(); + } + else + { + this.StatusCode = httpClient.StatusCode; + _responseData = GeneXus.Utils.RestAPIHelpers.ReadRestParameters(httpClient.ToString()); + } + } + } +} diff --git a/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestUtils.cs b/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestUtils.cs index f2198a30d..d5ec2a42d 100644 --- a/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestUtils.cs +++ b/dotnet/src/dotnetframework/GxClasses/Helpers/GXRestUtils.cs @@ -2,9 +2,17 @@ using System.Web; using GeneXus.Application; using GeneXus.Http; +using System.Collections.Generic; #if NETCORE using Microsoft.AspNetCore.Http; +using System.Text.Json; +using System.Text.Json.Serialization; #endif +using log4net; +using System.IO; +using Jayrock.Json; + + namespace GeneXus.Utils { @@ -87,4 +95,50 @@ public class UploadCachedFile public string fileExtension { get; set; } } + internal class RestAPIHelpers + { + static readonly ILog log = log4net.LogManager.GetLogger(typeof(GeneXus.Utils.RestAPIHelpers)); + + public static Dictionary ReadRestParameters(string restData) + { + var bodyParameters = new Dictionary(); + if (!String.IsNullOrEmpty(restData)) + { + try + { + var data = JSONHelper.ReadJSON(restData); + if (data is JObject jobj) + { + foreach (string name in jobj.Names) + { + bodyParameters.Add(name.ToLower(), jobj[name]); + } + } + else if (data is JArray jArray) + { + bodyParameters.Add(string.Empty, jArray); + } + } + catch (Exception ex) + { + GXLogging.Error(log, ex, "Parsing error in Body "); + } + } + return bodyParameters; + } + + public static Dictionary ReadRestBodyParameters(Stream stream) + { + var bodyParameters = new Dictionary(); + using (StreamReader streamReader = new StreamReader(stream)) + { + if (!streamReader.EndOfStream) + { + string json = streamReader.ReadToEnd(); + return ReadRestParameters(json); + } + } + return bodyParameters; + } + } } diff --git a/dotnet/src/dotnetframework/GxClasses/Helpers/GxDynamicCall.cs b/dotnet/src/dotnetframework/GxClasses/Helpers/GxDynamicCall.cs new file mode 100644 index 000000000..d6af1f832 --- /dev/null +++ b/dotnet/src/dotnetframework/GxClasses/Helpers/GxDynamicCall.cs @@ -0,0 +1,193 @@ +using GeneXus.Application; +using GeneXus.Metadata; +using GeneXus.Utils; +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace GeneXus.DynamicCall +{ + public class GxDynamicCall + { + private const string defaultMethod = "execute"; + private Assembly _assembly; + private GxDynCallProperties _properties; + private object _object; + public string ObjectName { get; set; } + public GxDynCallProperties Properties + { + get => _properties; + set + { + _properties = Properties; + } + } + + public GxDynamicCall() + { + _assembly= null; + _properties = new GxDynCallProperties(); + _object = null; + } + + private void VerifyDefaultProperties() { + _properties.NameSpace = string.IsNullOrEmpty(_properties.NameSpace) ? "GeneXus.Programs" : _properties.NameSpace; + + if (_assembly is null) + { + if (string.IsNullOrEmpty(_properties.AssemblyName)) + { + _assembly = Assembly.GetCallingAssembly(); + } + else + { + try + { + _assembly = Assembly.LoadFrom(_properties.AssemblyName); + } + catch + { + throw; + } + } + } + } + + public void Execute(ref IList parameters, out IList errors) + { + Create(null, out errors); + if (errors.Count == 0) + { + GxDynCallMethodConf methodConf = new GxDynCallMethodConf(); + Execute(ref parameters, methodConf, out errors); + } + } + + public void Create( IList constructParms, out IList errors) + { + errors = new GXBaseCollection(); + string objectNameToInvoke; + try + { + VerifyDefaultProperties(); + if (constructParms is null) + { + objectNameToInvoke = ObjectName; + } + else + { + objectNameToInvoke = _properties.ExternalName; + } + try + { + Type objType = ClassLoader.FindType(objectNameToInvoke, _properties.NameSpace, objectNameToInvoke.ToLower().Trim(), _assembly); + object[] constructorParameters; + if (constructParms != null && constructParms.Count > 0) + { + constructorParameters = new object[constructParms.Count]; + constructParms.CopyTo(constructorParameters, 0); + } + else + { + constructorParameters = new object[] { new GxContext() }; + } + _object = Activator.CreateInstance(objType, constructorParameters); + } + catch (Exception e) + { + GXUtil.ErrorToMessages("CreateInstance Error", e.Message, (GXBaseCollection) errors); + } + } + catch (Exception e) + { + GXUtil.ErrorToMessages("VerifyProperties Error", e.Message, (GXBaseCollection)errors); + } + } + public object Execute(ref IList parameters, GxDynCallMethodConf methodconfiguration , out IList errors) + { + object result; + errors = new GXBaseCollection(); + IList outParms= new List(); + + string methodName = methodconfiguration.MethodName; + bool isStatic = methodconfiguration.IsStatic; + + if (!isStatic) + { + if (_object != null) + { + try + { + outParms = ReflectionHelper.CallMethod(_object, (string.IsNullOrEmpty(methodName) ? defaultMethod : methodName), parameters); + } + catch (Exception e) + { + GXUtil.ErrorToMessages("CallMethod Error", e.Message, (GXBaseCollection)errors); + } + } + else + { + GXUtil.ErrorToMessages("NullInstance Error", "You must invoke create method before executing a non-static one", (GXBaseCollection)errors); + } + } + else + { + VerifyDefaultProperties(); + Type objType = ClassLoader.FindType(_properties.ExternalName, _properties.NameSpace, _properties.ExternalName.ToLower().Trim(), _assembly); + outParms = ReflectionHelper.CallMethod(objType, (string.IsNullOrEmpty(methodName) ? defaultMethod : methodName), parameters, isStatic); + } + if (outParms.Count > parameters.Count) + { + result = outParms[parameters.Count]; + outParms.RemoveAt(parameters.Count); + + } + else + { + result = null; + } + parameters = outParms; + return result; + } + + } + public class GxDynCallMethodConf + { + public bool IsStatic + { + get; set; + } + public string MethodName + { + get; set; + } + + public GxDynCallMethodConf() + { + IsStatic = false; + MethodName = "execute"; + } + + } + + public class GxDynCallProperties + { + public string ExternalName + { + get; + set; + } + public string AssemblyName + { + get; + set; + } + public string NameSpace + { + get; + set; + } + + } +} + diff --git a/dotnet/src/dotnetframework/GxClasses/Helpers/GxObjectProperties.cs b/dotnet/src/dotnetframework/GxClasses/Helpers/GxObjectProperties.cs new file mode 100644 index 000000000..cc735f09b --- /dev/null +++ b/dotnet/src/dotnetframework/GxClasses/Helpers/GxObjectProperties.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GeneXus.Utils; + +namespace GeneXus.Application +{ + public class GxObjectProperties + { + private GxLocation location = null; + private string errorMessage = String.Empty; + private int errorCode = 0; + private int statusCode = 0; + + public GxLocation Location { get => location; set => location = value; } + public string ErrorMessage { get => errorMessage; set => errorMessage = value; } + public int ErrorCode { get => errorCode; set => errorCode = value; } + public int StatusCode { get => statusCode; set => statusCode = value; } + } + + public class GxObjectsConfiguration { + + private Dictionary _properties = new Dictionary(); + public GxObjectProperties PropertiesFor(string objName) + { + if (!_properties.ContainsKey(objName)) + _properties[objName] = new GxObjectProperties(); + return _properties[objName]; + } + } +} diff --git a/dotnet/src/dotnetframework/GxClasses/Helpers/HttpHelper.cs b/dotnet/src/dotnetframework/GxClasses/Helpers/HttpHelper.cs index 8fb9bf054..109c871e6 100644 --- a/dotnet/src/dotnetframework/GxClasses/Helpers/HttpHelper.cs +++ b/dotnet/src/dotnetframework/GxClasses/Helpers/HttpHelper.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Primitives; using System.Net.Http; +using Microsoft.AspNetCore.Mvc.Formatters; #else using System.ServiceModel.Web; using System.ServiceModel; @@ -21,10 +22,6 @@ using System.Net; using System.Text; using System.Web; -using System.Threading.Tasks; -using System.Threading; -using System.Linq; -using GeneXus.Data; using System.Runtime.Serialization; using GeneXus.Mime; using System.Text.RegularExpressions; @@ -711,8 +708,37 @@ public static NameValueCollection GetParams(this HttpRequest request) return request.Params; #endif } +#if NETCORE + static readonly MediaType URLEncoded = new MediaType("application/x-www-form-urlencoded"); + public static string GetRawBodyString(this HttpRequest request, Encoding encoding = null) + { + if (encoding == null) + encoding = Encoding.UTF8; + if (!string.IsNullOrEmpty(request.ContentType)) + { + MediaType mediaType = new MediaType(request.ContentType); + if (mediaType.IsSubsetOf(URLEncoded)) + { + string content = string.Empty; + foreach (string key in request.Form.Keys) + { + if (request.Form.TryGetValue(key, out var value)) + { + content += $"{GXUtil.UrlEncode(key)}={GXUtil.UrlEncode(value)}&"; + } + } + content = content.TrimEnd('&'); + return content; + } + } + using (StreamReader sr = new StreamReader(request.Body, encoding)) + { + return sr.ReadToEnd(); + } + } +#endif public static string GetRawUrl(this HttpRequest request) { #if NETCORE diff --git a/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs b/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs index 027984fae..cdadf55fd 100644 --- a/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs +++ b/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs @@ -54,6 +54,9 @@ public abstract class GXHttpHandler : WebControl, IHttpHandler internal const string GX_SPA_GXOBJECT_RESPONSE_HEADER = "X-GXOBJECT"; internal const string GX_SPA_MASTERPAGE_HEADER = "X-SPA-MP"; internal const string GX_AJAX_MULTIPART_ID = "GXAjaxMultipart"; + private string ThemekbPrefix; + private string ThemestyleSheet; + private string ThemeurlBuildNumber; private const string GX_FULL_AJAX_REQUEST_HEADER = "X-FULL-AJAX-REQUEST"; private const string GXEVENT_PARM = "gxevent"; private const string URI_SEPARATOR = "/"; @@ -986,7 +989,12 @@ public virtual void webAjaxEvent() if (context.IsMultipartRequest) jsonRequest = cgiGet(GX_AJAX_MULTIPART_ID); else - jsonRequest = (new StreamReader(localHttpContext.Request.GetInputStream())).ReadToEnd(); + { + using (StreamReader reader = new StreamReader(localHttpContext.Request.GetInputStream())) + { + jsonRequest = reader.ReadToEnd(); + } + } string jsonResponse = dynAjaxEvent.Invoke(jsonRequest, this); @@ -1122,7 +1130,13 @@ public void AddStyleSheetFile(string styleSheet) AddStyleSheetFile(styleSheet, string.Empty); } - public void AddStyleSheetFile(string styleSheet, string urlBuildNumber, bool isDeferred = false) + public void AddStyleSheetFile(string styleSheet, string urlBuildNumber) + { + List userStyleSheetFiles = context.userStyleSheetFiles; + urlBuildNumber = context.GetURLBuildNumber(styleSheet, urlBuildNumber); + userStyleSheetFiles.Add(new string[] { styleSheet, urlBuildNumber }); + } + public void AddStyleSheetFile(string styleSheet, string urlBuildNumber, bool isDeferred) { urlBuildNumber = context.GetURLBuildNumber(styleSheet, urlBuildNumber); AddStyleSheetFile(styleSheet, urlBuildNumber, false, isDeferred); @@ -1134,13 +1148,15 @@ private void AddStyleSheetFile(string styleSheet, string urlBuildNumber, bool is if (!context.StyleSheetAdded(styleSheet)) { context.AddStyleSheetFile(styleSheet); + string sUncachedURL = context.GetCompleteURL(styleSheet) + urlBuildNumber; + string sLayerName = styleSheet.Replace("/", "_").Replace(".","_"); if (!context.HtmlHeaderClosed && context.isEnabled) { string sRelAtt = (isDeferred ? "rel=\"preload\" as=\"style\" " : "rel=\"stylesheet\""); if (isGxThemeHidden) - context.WriteHtmlTextNl(" @import url(\"" + sUncachedURL + "\") layer(" + sLayerName + ") "); } else { @@ -1181,9 +1197,7 @@ private Boolean FetchCustomCSS(ref string cssContent) return bSuccess && !String.IsNullOrEmpty(cssContent); } - - public void AddThemeStyleSheetFile(String kbPrefix, String styleSheet, string urlBuildNumber) - { + public void CloseStyles() { string cssContent = string.Empty; Boolean bHasCustomContent = FetchCustomCSS(ref cssContent); @@ -1193,18 +1207,29 @@ public void AddThemeStyleSheetFile(String kbPrefix, String styleSheet, string ur context.AddStyleSheetFile(GetPgmname()); } - string[] referencedFiles = ThemeHelper.GetThemeCssReferencedFiles(Path.GetFileNameWithoutExtension(styleSheet)); + string[] referencedFiles = ThemeHelper.GetThemeCssReferencedFiles(Path.GetFileNameWithoutExtension(this.ThemestyleSheet)); foreach (string file in referencedFiles) { string extension = Path.GetExtension(file); if (extension == ".css") { - AddStyleSheetFile(file, urlBuildNumber, bHasCustomContent); + AddStyleSheetFile(file, this.ThemeurlBuildNumber, bHasCustomContent); } else if (extension == ".js") - AddDeferredJavascriptSource(file, urlBuildNumber); + AddDeferredJavascriptSource(file, this.ThemeurlBuildNumber); + } + List userStyleSheetFiles = context.userStyleSheetFiles; + foreach (string[] data in userStyleSheetFiles) + { + AddStyleSheetFile(data[0], data[1], false, false); } - AddStyleSheetFile(kbPrefix + "Resources/" + context.GetLanguage() + "/" + styleSheet, urlBuildNumber, true, bHasCustomContent); + AddStyleSheetFile(this.ThemekbPrefix + "Resources/" + context.GetLanguage() + "/" + this.ThemestyleSheet, this.ThemeurlBuildNumber, true, bHasCustomContent); + } + public void AddThemeStyleSheetFile(String kbPrefix, String styleSheet, string urlBuildNumber) + { + this.ThemekbPrefix = kbPrefix; + this.ThemestyleSheet = styleSheet; + this.ThemeurlBuildNumber = urlBuildNumber; } public string GetCacheInvalidationToken() @@ -2094,7 +2119,8 @@ protected virtual void sendCacheHeaders() localHttpContext.Response.AddHeader("Cache-Control", HttpHelper.CACHE_CONTROL_HEADER_NO_CACHE_REVALIDATE); } } - + const string IE_COMP_EmulateIE7 = "EmulateIE7"; + const string IE_COMP_Edge = "edge"; public virtual void sendAdditionalHeaders() { if (IsSpaRequest()) @@ -2105,12 +2131,14 @@ public virtual void sendAdditionalHeaders() Config.GetValueOf("IE_COMPATIBILITY_VIEW", out IECompMode); if (!string.IsNullOrEmpty(IECompMode)) { - if (IECompMode.Equals("EmulateIE7") && !context.GetBrowserVersion().StartsWith("8")) //compatibility + if (IECompMode.Equals(IE_COMP_EmulateIE7) && !context.GetBrowserVersion().StartsWith("8")) //compatibility return; + + string safeIECompMode = IE_COMP_Edge.Equals(IE_COMP_EmulateIE7) ? IE_COMP_Edge : IE_COMP_Edge; #if NETCORE - localHttpContext.Response.Headers["X-UA-Compatible"] = "IE=" + IECompMode; + localHttpContext.Response.Headers["X-UA-Compatible"] = "IE=" + safeIECompMode; #else - localHttpContext.Response.AddHeader("X-UA-Compatible", "IE=" + IECompMode); + localHttpContext.Response.AddHeader("X-UA-Compatible", "IE=" + safeIECompMode); #endif } } diff --git a/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttpServices.cs b/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttpServices.cs index c6b87401c..100b1d8ea 100644 --- a/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttpServices.cs +++ b/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttpServices.cs @@ -73,11 +73,15 @@ public override void webExecute() { HttpRequest req = context.HttpContext.Request; string gxobj = GetNextPar().ToLower(); - string jsonStr = (new StreamReader(req.GetInputStream())).ReadToEnd(); GxSimpleCollection parmsColl = new GxSimpleCollection(); - if (!string.IsNullOrEmpty(jsonStr)) + + using (StreamReader stream = new StreamReader(req.GetInputStream())) { - parmsColl.FromJSonString(jsonStr); + string jsonStr = stream.ReadToEnd(); + if (!string.IsNullOrEmpty(jsonStr)) + { + parmsColl.FromJSonString(jsonStr); + } } #if NETCORE @@ -286,8 +290,8 @@ public override void webExecute() { localHttpContext.Response.ContentType = MediaTypesNames.TextPlain; var r = new List(); - var fileCount = localHttpContext.Request.GetFileCount(); - for (var i = 0; i < fileCount; i++) + int fileCount = localHttpContext.Request.GetFileCount(); + for (int i = 0; i < fileCount; i++) { string fileGuid = GxUploadHelper.GetUploadFileGuid(); string fileToken = GxUploadHelper.GetUploadFileId(fileGuid); @@ -321,14 +325,12 @@ public override void webExecute() GxUploadHelper.CacheUploadFile(fileGuid, Path.GetFileName(fName), ext, gxFile, context); } UploadFilesResult result = new UploadFilesResult() { files = r }; - var jsonObj = JSONHelper.Serialize(result); + string jsonObj = JSONHelper.Serialize(result); localHttpContext.Response.Write(jsonObj); } else - { - Stream istream = localHttpContext.Request.GetInputStream(); - string contentType = localHttpContext.Request.ContentType; - WcfExecute(istream, contentType); + { + WcfExecute(localHttpContext.Request.GetInputStream(), localHttpContext.Request.ContentType, (long)localHttpContext.Request.ContentLength); } } catch (Exception e) @@ -349,13 +351,13 @@ public override void webExecute() } - internal void WcfExecute(Stream istream, string contentType) + internal void WcfExecute(Stream istream, string contentType, long streamLength) { string ext, fName; ext = context.ExtensionForContentType(contentType); string tempDir = Preferences.getTMP_MEDIA_PATH(); - GxFile file = new GxFile(tempDir, FileUtil.getTempFileName(tempDir), GxFileType.PrivateAttribute); - file.Create(istream); + GxFile file = new GxFile(tempDir, FileUtil.getTempFileName(tempDir), GxFileType.PrivateAttribute); + file.Create(new NetworkInputStream(istream, streamLength)); JObject obj = new JObject(); fName = file.GetURI(); @@ -388,6 +390,58 @@ protected override GAMSecurityLevel IntegratedSecurityLevel } } } + + /// + /// Custom Network Stream for direct not multiparts uploads that do not support length operations + /// + internal class NetworkInputStream : Stream + { + private Stream innerStream; + private long streamLength; + + public NetworkInputStream(Stream s, long length): base() + { + innerStream = s; + streamLength = length; + } + + public override bool CanRead => innerStream.CanRead; + + public override bool CanSeek => innerStream.CanSeek; + + public override bool CanWrite => innerStream.CanWrite; + + public override long Length => streamLength; + + public override long Position { get => innerStream.Position; set => innerStream.Position = value; } + + public override void Flush() + { + innerStream.Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + return innerStream.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + return innerStream.Seek(offset, origin); + } + + public override void SetLength(long value) + { + innerStream.SetLength(value); + streamLength = value; + } + + public override void Write(byte[] buffer, int offset, int count) + { + innerStream.Write(buffer, offset, count); + } + } + public class UploadFilesResult { public List files; diff --git a/dotnet/src/dotnetframework/GxClasses/Services/GXRestServices.cs b/dotnet/src/dotnetframework/GxClasses/Services/GXRestServices.cs index 14d58d168..a319c5ae3 100644 --- a/dotnet/src/dotnetframework/GxClasses/Services/GXRestServices.cs +++ b/dotnet/src/dotnetframework/GxClasses/Services/GXRestServices.cs @@ -275,7 +275,8 @@ public bool RestParameter(string parameterName, string parameterValue) public void UploadImpl(Stream stream) { GXObjectUploadServices gxobject = new GXObjectUploadServices(context); - gxobject.WcfExecute(stream, WebOperationContext.Current.IncomingRequest.ContentType); + IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest; + gxobject.WcfExecute(stream, request.ContentType, request.ContentLength); } public void ErrorCheck(IGxSilentTrn trn) { diff --git a/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs b/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs index 294e876fa..a788e5b60 100644 --- a/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs +++ b/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs @@ -186,7 +186,6 @@ private Dictionary ReadBodyParameters() #endif } - private Dictionary SetAlias(Dictionary bodyParameters, Dictionary varAlias) { Dictionary parameters = new Dictionary(); @@ -389,41 +388,11 @@ public virtual Task Patch(object key) { return MethodBodyExecute(key); } - public Dictionary ReadRequestParameters(Stream stream) { - var bodyParameters = new Dictionary(); - using (StreamReader streamReader = new StreamReader(stream)) - { - if (!streamReader.EndOfStream) - { - try - { - string json = streamReader.ReadToEnd(); - var data = JSONHelper.ReadJSON(json); - JObject jobj = data as JObject; - JArray jArray = data as JArray; - if (jobj != null) - { - foreach (string name in jobj.Names) - { - bodyParameters.Add(name.ToLower(), jobj[name]); - } - } - else if (jArray != null) - { - bodyParameters.Add(string.Empty, jArray); - } - } - catch (Exception ex) - { - GXLogging.Error(log, ex, "Parsing error in Body "); - - } - } - } - return bodyParameters; + return RestAPIHelpers.ReadRestBodyParameters(stream); } + protected IDictionary ReadQueryParameters(Dictionary varAlias) { NameValueCollection query = _httpContext.Request.GetQueryString(); @@ -745,13 +714,7 @@ protected Task Serialize(Dictionary parameters, Dictionary parameters, Dictionary parameters, Dictionary fmtParameters) + { + DateTime udt = (dt==DateTimeUtil.NullDate()) ? dt: dt.ToUniversalTime(); + + if (fmtParameters.ContainsKey(key) && !String.IsNullOrEmpty(fmtParameters[key])) + { + return DateTimeUtil.DToC2(udt, fmtParameters[key]); + } + return udt; + } + private bool PrimitiveType(Type type) { return type.IsPrimitive || type == typeof(string) || type.IsValueType; diff --git a/dotnet/src/dotnetframework/GxClasses/Services/ReflectionHelper.cs b/dotnet/src/dotnetframework/GxClasses/Services/ReflectionHelper.cs index 8cd27f4b5..85e02c6b7 100644 --- a/dotnet/src/dotnetframework/GxClasses/Services/ReflectionHelper.cs +++ b/dotnet/src/dotnetframework/GxClasses/Services/ReflectionHelper.cs @@ -49,12 +49,36 @@ public static Dictionary CallMethod(object instance, String meth MethodInfo methodInfo = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); return CallMethodImpl(instance, methodInfo, parameters, context); } + public static IList CallMethod(object instanceOrType, String methodName, IList parameters, bool isStatic = false, IGxContext context = null) + { + MethodInfo methodInfo; + object instance = null; + if (isStatic) + { + methodInfo = ((Type)instanceOrType).GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase); + } + else + { + + methodInfo = instanceOrType.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); + instance = instanceOrType; + } + return CallMethodImpl(instance, methodInfo, parameters, context); + } static Dictionary CallMethodImpl(object instance, MethodInfo methodInfo, IDictionary parameters, IGxContext context) { object[] parametersForInvocation = ProcessParametersForInvoke(methodInfo, parameters, context); object returnParm = methodInfo.Invoke(instance, parametersForInvocation); return ProcessParametersAfterInvoke(methodInfo, parametersForInvocation, returnParm); } + static IList CallMethodImpl(object instance, MethodInfo methodInfo, IList parameters, IGxContext context) + { + object[] parametersForInvocation = ProcessParametersForInvoke(methodInfo, parameters, context); + object returnParm = methodInfo.Invoke(instance, parametersForInvocation); + IList parametersAfterInvoke = parametersForInvocation.ToList(); + parametersAfterInvoke.Add(returnParm); + return parametersAfterInvoke; + } public static bool MethodHasInputParameters(object instance, String methodName) { MethodInfo methodInfo = instance.GetType().GetMethod(methodName); @@ -107,16 +131,16 @@ public static Dictionary GetWrappedParameter(object instance, St private static object ConvertSingleJsonItem(object value, Type newType, IGxContext context) { - if (value!= null && value.GetType() == newType) + if (value != null && value.GetType() == newType) { return value; } else if (typeof(IGxJSONAble).IsAssignableFrom(newType)) { object TObject; - if (typeof(GxSilentTrnSdt).IsAssignableFrom(newType) && context!=null) + if (typeof(GxSilentTrnSdt).IsAssignableFrom(newType) && context != null) { - TObject = Activator.CreateInstance(newType, new object[] { context}); + TObject = Activator.CreateInstance(newType, new object[] { context }); } else { @@ -155,9 +179,9 @@ private static object ConvertSingleJsonItem(object value, Type newType, IGxConte } } - private static object ConvertStringToNewNonNullableType(object value, Type newType, IGxContext context=null) + private static object ConvertStringToNewNonNullableType(object value, Type newType, IGxContext context = null) { - + if (newType.IsArray) { // For comma separated list @@ -174,7 +198,7 @@ private static object ConvertStringToNewNonNullableType(object value, Type newTy return ConvertSingleJsonItem(value, newType, context); } - internal static object ConvertStringToNewType(object value, Type newType, IGxContext context=null) + internal static object ConvertStringToNewType(object value, Type newType, IGxContext context = null) { // If it's not a nullable type, just pass through the parameters to Convert.ChangeType if (newType.GetTypeInfo().IsGenericType && newType.GetGenericTypeDefinition() != null && newType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) @@ -191,9 +215,9 @@ internal static object ConvertStringToNewType(object value, Type newType, IGxCon public static Dictionary ParametersFormat(object instance, string methodName) { MethodInfo methodInfo = instance.GetType().GetMethod(methodName); - + Dictionary formatList = new Dictionary(); - var methodParameters = methodInfo.GetParameters(); + var methodParameters = methodInfo.GetParameters(); foreach (var methodParameter in methodParameters) { var gxParameterName = GxParameterName(methodParameter.Name); @@ -210,6 +234,7 @@ public static Dictionary ParametersFormat(object instance, strin return formatList; } + private static Dictionary ProcessParametersAfterInvoke(MethodInfo methodInfo, object[] parametersForInvocation, object returnParm) { Dictionary outputParameters = new Dictionary(); @@ -230,7 +255,7 @@ private static Dictionary ProcessParametersAfterInvoke(MethodInf } - internal static object[] ProcessParametersForInvoke(MethodInfo methodInfo, IDictionary parameters, IGxContext context=null) + internal static object[] ProcessParametersForInvoke(MethodInfo methodInfo, IDictionary parameters, IGxContext context = null) { var methodParameters = methodInfo.GetParameters(); object[] parametersForInvocation = new object[methodParameters.Length]; @@ -238,14 +263,14 @@ internal static object[] ProcessParametersForInvoke(MethodInfo methodInfo, IDict foreach (var methodParameter in methodParameters) { object value; - + var gxParameterName = GxParameterName(methodParameter.Name).ToLower(); Type parmType = methodParameter.ParameterType; if (IsByRefParameter(methodParameter)) { parmType = parmType.GetElementType(); } - if (parameters!=null && parameters.TryGetValue(gxParameterName, out value)) + if (parameters != null && parameters.TryGetValue(gxParameterName, out value)) { if (value == null || JSONHelper.IsJsonNull(value)) { @@ -266,6 +291,41 @@ internal static object[] ProcessParametersForInvoke(MethodInfo methodInfo, IDict } return parametersForInvocation; } + + internal static object[] ProcessParametersForInvoke(MethodInfo methodInfo, IList parameters, IGxContext context = null) + { + var methodParameters = methodInfo.GetParameters(); + object[] parametersForInvocation = new object[methodParameters.Length]; + var idx = 0; + foreach (var methodParameter in methodParameters) + { + Type parmType = methodParameter.ParameterType; + if (IsByRefParameter(methodParameter)) + { + parmType = parmType.GetElementType(); + } + object value = parameters.ElementAt(idx); + if (!value.GetType().Equals(parmType)) + { + //To avoid convertion from string type + if (value.GetType() != typeof(string)) + { + var convertedValue = ConvertStringToNewType(value, parmType, context); + parametersForInvocation[idx] = convertedValue; + } + else + { + throw new ArgumentException("Type does not match", methodParameter.Name); + } + } + else + { + parametersForInvocation[idx] = value; + } + idx++; + } + return parametersForInvocation; + } private static Regex attVar = new Regex(@"^AV?\d{1,}", RegexOptions.Compiled); private static string GxParameterName(string methodParameterName) { diff --git a/dotnet/src/dotnetframework/GxClasses/View/GXWebControls.cs b/dotnet/src/dotnetframework/GxClasses/View/GXWebControls.cs index 5beefb333..16b54116b 100644 --- a/dotnet/src/dotnetframework/GxClasses/View/GXWebControls.cs +++ b/dotnet/src/dotnetframework/GxClasses/View/GXWebControls.cs @@ -41,7 +41,7 @@ private static Type GetWebStdType(GeneXus.Application.IGxContext context) } } #else - var cname = "GxWebStd"; + string cname = "GxWebStd"; string mainNamespace, className; if (Config.GetValueOf("AppMainNamespace", out mainNamespace)) className = mainNamespace + "." + cname; @@ -1658,7 +1658,7 @@ public override void FromJSONObject(dynamic Obj) JArray jsonArrValues = (JArray)jsonObj["v"]; if (jsonArrValues != null) { - var idx = 1; + int idx = 1; for (int i = 0; i < jsonArrValues.Count; i++) { JArray jsonItem = jsonArrValues.GetArray(i); diff --git a/dotnet/src/dotnetframework/GxDataInitialization/GXDataInitialization.csproj b/dotnet/src/dotnetframework/GxDataInitialization/GXDataInitialization.csproj index 4f6b4a8cd..a54201c6f 100644 --- a/dotnet/src/dotnetframework/GxDataInitialization/GXDataInitialization.csproj +++ b/dotnet/src/dotnetframework/GxDataInitialization/GXDataInitialization.csproj @@ -9,8 +9,7 @@ GeneXus.DataInitialization - - 2.0.11 + runtime diff --git a/dotnet/src/dotnetframework/GxMail/GxMail.csproj b/dotnet/src/dotnetframework/GxMail/GxMail.csproj index bd0365b94..0f121131f 100644 --- a/dotnet/src/dotnetframework/GxMail/GxMail.csproj +++ b/dotnet/src/dotnetframework/GxMail/GxMail.csproj @@ -15,7 +15,7 @@ - + diff --git a/dotnet/src/dotnetframework/Projects/StoreManager/Store/Util.cs b/dotnet/src/dotnetframework/Projects/StoreManager/Store/Util.cs index 9a6440a7e..ce6a2a344 100644 --- a/dotnet/src/dotnetframework/Projects/StoreManager/Store/Util.cs +++ b/dotnet/src/dotnetframework/Projects/StoreManager/Store/Util.cs @@ -1,13 +1,8 @@ -using GeneXus.Application; using GeneXus.Utils; using Jayrock.Json; using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Security.Cryptography; using System.Text; -using System.Threading.Tasks; namespace GeneXus.SD.Store { @@ -31,7 +26,7 @@ public static JObject FromJSonString(string s) private static byte[] GetHash(string inputString) { - HashAlgorithm algorithm = MD5.Create(); + HashAlgorithm algorithm = SHA256.Create(); return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString)); } diff --git a/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj b/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj index 7a72a5e7a..39fa35871 100644 --- a/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj +++ b/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj @@ -9,12 +9,9 @@ GeneXus.StoreManager - - - - + - + diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/ExternalProviderS3.cs b/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/ExternalProviderS3.cs index 91faea310..163078cf9 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/ExternalProviderS3.cs +++ b/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/ExternalProviderS3.cs @@ -2,10 +2,10 @@ using Amazon.S3; using Amazon.S3.IO; using Amazon.S3.Model; -using GeneXus.Encryption; + +using Amazon.S3.Transfer; using GeneXus.Services; using GeneXus.Utils; -using log4net; using System; using System.Collections.Generic; using System.IO; @@ -96,6 +96,13 @@ private void Initialize() { config.ServiceURL = Endpoint; customEndpoint = true; } + else + { + if (region == Amazon.RegionEndpoint.USEast1) + { + Amazon.AWSConfigsS3.UseSignatureVersion4 = true; + } + } #if NETCORE if (credentials != null) @@ -362,21 +369,59 @@ private S3CannedACL GetCannedACL(GxFileType acl) } } + const long MIN_MULTIPART_POST = 1024 * 1024 * 5; //5MB + const long MULITIPART_POST_PART_SIZE = 1024 * 1024 * 6; // 6 MB. + public string Upload(string fileName, Stream stream, GxFileType destFileType) { - MemoryStream ms = new MemoryStream(); - stream.CopyTo(ms);//can determine PutObjectRequest.Headers.ContentLength. Avoid error Could not determine content length + bool doSimpleUpload = stream.Length <= MIN_MULTIPART_POST; + if (doSimpleUpload) + { + return UploadSimple(fileName, stream, destFileType); + } + else + { + return UploadMultipart(fileName, stream, destFileType); + } + } + + private string UploadMultipart(string fileName, Stream stream, GxFileType destFileType) + { + TransferUtility transfer = new TransferUtility(Client); + var uploadRequest = new TransferUtilityUploadRequest + { + BucketName = Bucket, + Key = fileName, + PartSize = MULITIPART_POST_PART_SIZE, + InputStream = stream, + CannedACL = GetCannedACL(destFileType) + }; + + if (TryGetContentType(fileName, out string mimeType)) + { + uploadRequest.ContentType = mimeType; + } + + transfer.Upload(uploadRequest); + + return Get(fileName, destFileType); + } + + private string UploadSimple(string fileName, Stream stream, GxFileType destFileType) + { PutObjectRequest objectRequest = new PutObjectRequest() { BucketName = Bucket, Key = fileName, - InputStream = ms, + InputStream = stream, CannedACL = GetCannedACL(destFileType) }; - if (TryGetContentType(fileName, out string mimeType)) { + if (TryGetContentType(fileName, out string mimeType)) + { objectRequest.ContentType = mimeType; } - PutObjectResponse result = PutObject(objectRequest); + PutObject(objectRequest); + return Get(fileName, destFileType); } diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj b/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj index af52d1e4c..be853d2d5 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj +++ b/dotnet/src/dotnetframework/Providers/Storage/GXAmazonS3/GXAmazonS3.csproj @@ -7,7 +7,7 @@ GeneXus.Amazon - + diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/ExternalProviderGoogle.cs b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/ExternalProviderGoogle.cs index db2714e3c..7d6042b7b 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/ExternalProviderGoogle.cs +++ b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/ExternalProviderGoogle.cs @@ -49,6 +49,19 @@ public ExternalProviderGoogle() : this(null) public ExternalProviderGoogle(GXService providerService) : base(providerService) { +#if NETFRAMEWORK + AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => + { + if (args.Name.StartsWith(nameof(Google))) + { + int sep = args.Name.IndexOf(','); + if (sep != -1) + return System.Reflection.Assembly.Load(args.Name.Remove(sep)); + } + + return null; + }; +#endif Initialize(); } diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj index e6e383036..e8dd2dcb3 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj +++ b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj @@ -1,4 +1,4 @@ - + net462 GXGoogleCloud @@ -8,15 +8,8 @@ - - - - - - - - - + + diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/app.config b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/app.config index 70e434f96..612d6bc68 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/app.config +++ b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/app.config @@ -1,34 +1,30 @@ - + - - - - - + - + - + - + - + - + diff --git a/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj b/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj index 7eed85316..1d0f68bd7 100644 --- a/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj +++ b/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj @@ -3,17 +3,18 @@ net6.0 Exe v4 + false - + - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj index 8a851d152..f211b6d98 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj @@ -32,12 +32,12 @@ - - - - + + + + - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj index 7955fec80..e08a5bade 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj @@ -34,7 +34,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricCipher.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricCipher.cs index 9665c60b7..6b41fad95 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricCipher.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricCipher.cs @@ -15,357 +15,357 @@ namespace GeneXusCryptography.Asymmetric { - /// - /// Implements Asymmetric Block Cipher Engines and methods to encrypt and decrypt - /// - [SecuritySafeCritical] - public class AsymmetricCipher : SecurityAPIObject, IAsymmetricCipherObject - { - - /// - /// AsymmetricCipher class constructor - /// - public AsymmetricCipher() : base() - { - - } - - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - - [SecuritySafeCritical] - public string DoEncrypt_WithPrivateKey(string hashAlgorithm, string asymmetricEncryptionPadding, PrivateKeyManager key, string plainText) - { - - if (this.HasError() || key == null) - { - return ""; - } - return DoEncryptInternal(hashAlgorithm, asymmetricEncryptionPadding, key, true, plainText); - } - - [SecuritySafeCritical] - public string DoEncrypt_WithPublicKey(string hashAlgorithm, string asymmetricEncryptionPadding, CertificateX509 certificate, string plainText) - { - - if (this.HasError() || certificate == null) - { - return ""; - } - return DoEncryptInternal(hashAlgorithm, asymmetricEncryptionPadding, certificate, false, plainText); - } - - [SecuritySafeCritical] - public string DoDecrypt_WithPrivateKey(string hashAlgorithm, string asymmetricEncryptionPadding, PrivateKeyManager key, string encryptedInput) - { - - if (this.HasError() || key == null) - { - return ""; - } - return DoDecryptInternal(hashAlgorithm, asymmetricEncryptionPadding, key, true, encryptedInput); - } - - [SecuritySafeCritical] - public string DoDecrypt_WithPublicKey(string hashAlgorithm, string asymmetricEncryptionPadding, CertificateX509 certificate, string encryptedInput) - { - - if (this.HasError() || certificate == null) - { - return ""; - } - return DoDecryptInternal(hashAlgorithm, asymmetricEncryptionPadding, certificate, false, encryptedInput); - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - - /// - /// Encrypts the string encoded plain text - /// - /// string AsymmetricEncryptionAlgorithm enum, algorithm name - /// string HashAlgorithm enum, algorithm name - /// string AsymmetricEncryptionPadding enum, padding name - /// string path to key/certificate - /// boolean true if key is private, false if it is public - /// string keystore/certificate pkcs12 format alias - /// Srting keysore/certificate pkcs12 format alias - /// string to encrypt - /// string Base64 encrypted plainText text - private string DoEncryptInternal(string hashAlgorithm, string asymmetricEncryptionPadding, Key key, bool isPrivate, string plainText) - { - this.error.cleanError(); - - HashAlgorithm hash = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error); - AsymmetricEncryptionPadding padding = AsymmetricEncryptionPaddingUtils.getAsymmetricEncryptionPadding(asymmetricEncryptionPadding, this.error); - if (this.error.existsError()) - { - return ""; - } - - string asymmetricEncryptionAlgorithm = ""; - AsymmetricKeyParameter asymKey = null; - if (isPrivate) - { - PrivateKeyManager keyMan = (PrivateKeyManager)key; - if (!keyMan.HasPrivateKey || keyMan.HasError()) - { - this.error = keyMan.GetError(); - return ""; - } - asymmetricEncryptionAlgorithm = keyMan.getPrivateKeyAlgorithm(); - - asymKey = keyMan.getPrivateKeyParameterForEncryption(); - if (keyMan.HasError()) - { - this.error = keyMan.GetError(); - return ""; - } - } - else - { - CertificateX509 cert = (CertificateX509)key; - if (!cert.Inicialized || cert.HasError()) - { - this.error = cert.GetError(); - return ""; - } - asymmetricEncryptionAlgorithm = cert.getPublicKeyAlgorithm(); - asymKey = cert.getPublicKeyParameterForEncryption(); - if (cert.HasError()) - { - this.error = cert.GetError(); - return ""; - } - } - - AsymmetricEncryptionAlgorithm algorithm = AsymmetricEncryptionAlgorithmUtils - .getAsymmetricEncryptionAlgorithm(asymmetricEncryptionAlgorithm, this.error); - try - { - return doEncrypt(algorithm, hash, padding, asymKey, plainText); - } - catch (InvalidCipherTextException) - { - this.error.setError("AE036", "Algoritmo inválido" + algorithm); - - return ""; - } - } - - - /// - /// Decrypts the base64 encoded encrypted text - /// - /// string AsymmetricEncryptionAlgorithm enum, algorithm name - /// string HashAlgorithm enum, algorithm name - /// string AsymmetricEncryptionPadding enum, padding name - /// string path to key/certificate - /// boolean true if key is private, false if it is public - /// string keystore/certificate pkcs12 format alias - /// Srting keysore/certificate pkcs12 format alias - /// - /// string decypted encryptedInput text - private string DoDecryptInternal(string hashAlgorithm, string asymmetricEncryptionPadding, Key key, bool isPrivate, string encryptedInput) - { - this.error.cleanError(); - - HashAlgorithm hash = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error); - AsymmetricEncryptionPadding padding = AsymmetricEncryptionPaddingUtils.getAsymmetricEncryptionPadding(asymmetricEncryptionPadding, this.error); - if (this.error.existsError()) - { - return ""; - } - string asymmetricEncryptionAlgorithm = ""; - AsymmetricKeyParameter asymKey = null; - - if (isPrivate) - { - PrivateKeyManager keyMan = (PrivateKeyManager)key; - if (!keyMan.HasPrivateKey || keyMan.HasError()) - { - this.error = keyMan.GetError(); - return ""; - } - asymmetricEncryptionAlgorithm = keyMan.getPrivateKeyAlgorithm(); - - asymKey = keyMan.getPrivateKeyParameterForEncryption(); - if (keyMan.HasError()) - { - this.error = keyMan.GetError(); - return ""; - } - } - else - { - CertificateX509 cert = (CertificateX509)key; - if (!cert.Inicialized || cert.HasError()) - { - this.error = cert.GetError(); - return ""; - } - asymmetricEncryptionAlgorithm = cert.getPublicKeyAlgorithm(); - asymKey = cert.getPublicKeyParameterForEncryption(); - if (cert.HasError()) - { - this.error = cert.GetError(); - return ""; - } - } - - AsymmetricEncryptionAlgorithm algorithm = AsymmetricEncryptionAlgorithmUtils - .getAsymmetricEncryptionAlgorithm(asymmetricEncryptionAlgorithm, this.error); - - - try - { - this.error.cleanError(); - return doDecrypt(algorithm, hash, padding, asymKey, encryptedInput); - } - catch (InvalidCipherTextException e) - { - this.error.setError("AE039", "Algoritmo inválido" + algorithm); - throw new InvalidCipherTextException("Algoritmo inválido" + algorithm, e); - } - } - - /// - /// Decrypts the base64 encoded encrypted text - /// - /// string AsymmetricEncryptionAlgorithm enum, algorithm name - /// string HashAlgorithm enum, algorithm name - /// string AsymmetricEncryptionPadding enum, padding name - /// AsymmetricKeyParameter with loaded key for specified algorithm - /// string Base64 to decrypt - /// string decypted encryptedInput text - private string doDecrypt(AsymmetricEncryptionAlgorithm asymmetricEncryptionAlgorithm, HashAlgorithm hashAlgorithm, AsymmetricEncryptionPadding asymmetricEncryptionPadding, AsymmetricKeyParameter asymmetricKeyParameter, string encryptedInput) - { - - IAsymmetricBlockCipher asymEngine = getEngine(asymmetricEncryptionAlgorithm); - IDigest hash = getDigest(hashAlgorithm); - IAsymmetricBlockCipher cipher = getPadding(asymEngine, hash, asymmetricEncryptionPadding); - BufferedAsymmetricBlockCipher bufferedCipher = new BufferedAsymmetricBlockCipher(cipher); - if (this.error.existsError()) - { - return ""; - } - bufferedCipher.Init(false, asymmetricKeyParameter); - byte[] inputBytes = Base64.Decode(encryptedInput); - bufferedCipher.ProcessBytes(inputBytes, 0, inputBytes.Length); - byte[] outputBytes = bufferedCipher.DoFinal(); - if (outputBytes == null || outputBytes.Length == 0) - { - this.error.setError("AE040", "Asymmetric decryption error"); - return ""; - } - EncodingUtil eu = new EncodingUtil(); - this.error = eu.GetError(); - return eu.getString(outputBytes); - - - } - /// - /// Encrypts the string encoded plain text - /// - /// - /// - /// - /// - /// - /// Base64 encrypted encryptedInput text - private string doEncrypt(AsymmetricEncryptionAlgorithm asymmetricEncryptionAlgorithm, HashAlgorithm hashAlgorithm, AsymmetricEncryptionPadding asymmetricEncryptionPadding, AsymmetricKeyParameter asymmetricKeyParameter, string plainText) - { - IAsymmetricBlockCipher asymEngine = getEngine(asymmetricEncryptionAlgorithm); - IDigest hash = getDigest(hashAlgorithm); - IAsymmetricBlockCipher cipher = getPadding(asymEngine, hash, asymmetricEncryptionPadding); - BufferedAsymmetricBlockCipher bufferedCipher = new BufferedAsymmetricBlockCipher(cipher); - if (this.error.existsError()) - { - return ""; - } - bufferedCipher.Init(true, asymmetricKeyParameter); - EncodingUtil eu = new EncodingUtil(); - byte[] inputBytes = eu.getBytes(plainText); - if (eu.GetError().existsError()) - { - this.error = eu.GetError(); - return ""; - } - bufferedCipher.ProcessBytes(inputBytes, 0, inputBytes.Length); - byte[] outputBytes = bufferedCipher.DoFinal(); - if (outputBytes == null || outputBytes.Length == 0) - { - this.error.setError("AE041", "Asymmetric encryption error"); - return ""; - } - this.error.cleanError(); - return Base64.ToBase64String(outputBytes); - - } - /// - /// Build asymmetric block cipher engine - /// - /// AsymmetricEncryptionAlgorithm enum, algorithm name - /// IAsymmetricBlockCipher Engine for the specified algorithm - private IAsymmetricBlockCipher getEngine(AsymmetricEncryptionAlgorithm asymmetricEncryptionAlgorithm) - { - - switch (asymmetricEncryptionAlgorithm) - { - case AsymmetricEncryptionAlgorithm.RSA: - return new RsaEngine(); - default: - this.error.setError("AE042", "Unrecognized algorithm"); - return null; - } - - } - /// - /// Build Digest engine for asymmetric block cipher and signing - /// - /// HashAlgorithm enum, algorithm name - /// IDigest Engine for the specified algorithm - private IDigest getDigest(HashAlgorithm hashAlgorithm) - { - Hashing hash = new Hashing(); - IDigest digest = hash.createHash(hashAlgorithm); - if (digest == null) - { - this.error.setError("AE043", "Unrecognized HashAlgorithm"); - return null; - } - return digest; - } - /// - /// Buils Asymmetric Block Cipher engine - /// - /// AsymmetricBlockCipher enum, algorithm name - /// Digest Engine for hashing - /// AsymmetricEncryptionPadding enum, padding name - /// AsymmetricBlockCipher Engine specific for the algoritm, hash and padding - private IAsymmetricBlockCipher getPadding(IAsymmetricBlockCipher asymBlockCipher, IDigest hash, AsymmetricEncryptionPadding asymmetricEncryptionPadding) - { - switch (asymmetricEncryptionPadding) - { - case AsymmetricEncryptionPadding.NOPADDING: - return null; - case AsymmetricEncryptionPadding.OAEPPADDING: - if (hash != null) - { - return new OaepEncoding(asymBlockCipher, hash); - } - else - { - return new OaepEncoding(asymBlockCipher); - } - case AsymmetricEncryptionPadding.PCKS1PADDING: - return new Pkcs1Encoding(asymBlockCipher); - case AsymmetricEncryptionPadding.ISO97961PADDING: - return new ISO9796d1Encoding(asymBlockCipher); - default: - error.setError("AE044", "Unrecognized AsymmetricEncryptionPadding"); - return null; - } - } - } + /// + /// Implements Asymmetric Block Cipher Engines and methods to encrypt and decrypt + /// + [SecuritySafeCritical] + public class AsymmetricCipher : SecurityAPIObject, IAsymmetricCipherObject + { + + /// + /// AsymmetricCipher class constructor + /// + public AsymmetricCipher() : base() + { + + } + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + [SecuritySafeCritical] + public string DoEncrypt_WithPrivateKey(string hashAlgorithm, string asymmetricEncryptionPadding, PrivateKeyManager key, string plainText) + { + + if (this.HasError() || key == null) + { + return ""; + } + return DoEncryptInternal(hashAlgorithm, asymmetricEncryptionPadding, key, true, plainText); + } + + [SecuritySafeCritical] + public string DoEncrypt_WithPublicKey(string hashAlgorithm, string asymmetricEncryptionPadding, CertificateX509 certificate, string plainText) + { + + if (this.HasError() || certificate == null) + { + return ""; + } + return DoEncryptInternal(hashAlgorithm, asymmetricEncryptionPadding, certificate, false, plainText); + } + + [SecuritySafeCritical] + public string DoDecrypt_WithPrivateKey(string hashAlgorithm, string asymmetricEncryptionPadding, PrivateKeyManager key, string encryptedInput) + { + + if (this.HasError() || key == null) + { + return ""; + } + return DoDecryptInternal(hashAlgorithm, asymmetricEncryptionPadding, key, true, encryptedInput); + } + + [SecuritySafeCritical] + public string DoDecrypt_WithPublicKey(string hashAlgorithm, string asymmetricEncryptionPadding, CertificateX509 certificate, string encryptedInput) + { + + if (this.HasError() || certificate == null) + { + return ""; + } + return DoDecryptInternal(hashAlgorithm, asymmetricEncryptionPadding, certificate, false, encryptedInput); + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + + /// + /// Encrypts the string encoded plain text + /// + /// string AsymmetricEncryptionAlgorithm enum, algorithm name + /// string HashAlgorithm enum, algorithm name + /// string AsymmetricEncryptionPadding enum, padding name + /// string path to key/certificate + /// boolean true if key is private, false if it is public + /// string keystore/certificate pkcs12 format alias + /// Srting keysore/certificate pkcs12 format alias + /// string to encrypt + /// string Base64 encrypted plainText text + private string DoEncryptInternal(string hashAlgorithm, string asymmetricEncryptionPadding, Key key, bool isPrivate, string plainText) + { + this.error.cleanError(); + + HashAlgorithm hash = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error); + AsymmetricEncryptionPadding padding = AsymmetricEncryptionPaddingUtils.getAsymmetricEncryptionPadding(asymmetricEncryptionPadding, this.error); + if (this.error.existsError()) + { + return ""; + } + + string asymmetricEncryptionAlgorithm = ""; + AsymmetricKeyParameter asymKey = null; + if (isPrivate) + { + PrivateKeyManager keyMan = (PrivateKeyManager)key; + if (!keyMan.HasPrivateKey || keyMan.HasError()) + { + this.error = keyMan.GetError(); + return ""; + } + asymmetricEncryptionAlgorithm = keyMan.getPrivateKeyAlgorithm(); + + asymKey = keyMan.getPrivateKeyParameterForEncryption(); + if (keyMan.HasError()) + { + this.error = keyMan.GetError(); + return ""; + } + } + else + { + CertificateX509 cert = (CertificateX509)key; + if (!cert.Inicialized || cert.HasError()) + { + this.error = cert.GetError(); + return ""; + } + asymmetricEncryptionAlgorithm = cert.getPublicKeyAlgorithm(); + asymKey = cert.getPublicKeyParameterForEncryption(); + if (cert.HasError()) + { + this.error = cert.GetError(); + return ""; + } + } + + AsymmetricEncryptionAlgorithm algorithm = AsymmetricEncryptionAlgorithmUtils + .getAsymmetricEncryptionAlgorithm(asymmetricEncryptionAlgorithm, this.error); + try + { + return doEncrypt(algorithm, hash, padding, asymKey, plainText); + } + catch (InvalidCipherTextException) + { + this.error.setError("AE036", "Algoritmo inválido" + algorithm); + + return ""; + } + } + + + /// + /// Decrypts the base64 encoded encrypted text + /// + /// string AsymmetricEncryptionAlgorithm enum, algorithm name + /// string HashAlgorithm enum, algorithm name + /// string AsymmetricEncryptionPadding enum, padding name + /// string path to key/certificate + /// boolean true if key is private, false if it is public + /// string keystore/certificate pkcs12 format alias + /// Srting keysore/certificate pkcs12 format alias + /// + /// string decypted encryptedInput text + private string DoDecryptInternal(string hashAlgorithm, string asymmetricEncryptionPadding, Key key, bool isPrivate, string encryptedInput) + { + this.error.cleanError(); + + HashAlgorithm hash = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error); + AsymmetricEncryptionPadding padding = AsymmetricEncryptionPaddingUtils.getAsymmetricEncryptionPadding(asymmetricEncryptionPadding, this.error); + if (this.error.existsError()) + { + return ""; + } + string asymmetricEncryptionAlgorithm = ""; + AsymmetricKeyParameter asymKey = null; + + if (isPrivate) + { + PrivateKeyManager keyMan = (PrivateKeyManager)key; + if (!keyMan.HasPrivateKey || keyMan.HasError()) + { + this.error = keyMan.GetError(); + return ""; + } + asymmetricEncryptionAlgorithm = keyMan.getPrivateKeyAlgorithm(); + + asymKey = keyMan.getPrivateKeyParameterForEncryption(); + if (keyMan.HasError()) + { + this.error = keyMan.GetError(); + return ""; + } + } + else + { + CertificateX509 cert = (CertificateX509)key; + if (!cert.Inicialized || cert.HasError()) + { + this.error = cert.GetError(); + return ""; + } + asymmetricEncryptionAlgorithm = cert.getPublicKeyAlgorithm(); + asymKey = cert.getPublicKeyParameterForEncryption(); + if (cert.HasError()) + { + this.error = cert.GetError(); + return ""; + } + } + + AsymmetricEncryptionAlgorithm algorithm = AsymmetricEncryptionAlgorithmUtils + .getAsymmetricEncryptionAlgorithm(asymmetricEncryptionAlgorithm, this.error); + + + try + { + this.error.cleanError(); + return doDecrypt(algorithm, hash, padding, asymKey, encryptedInput); + } + catch (InvalidCipherTextException e) + { + this.error.setError("AE039", "Algoritmo inválido" + algorithm); + throw new InvalidCipherTextException("Algoritmo inválido" + algorithm, e); + } + } + + /// + /// Decrypts the base64 encoded encrypted text + /// + /// string AsymmetricEncryptionAlgorithm enum, algorithm name + /// string HashAlgorithm enum, algorithm name + /// string AsymmetricEncryptionPadding enum, padding name + /// AsymmetricKeyParameter with loaded key for specified algorithm + /// string Base64 to decrypt + /// string decypted encryptedInput text + private string doDecrypt(AsymmetricEncryptionAlgorithm asymmetricEncryptionAlgorithm, HashAlgorithm hashAlgorithm, AsymmetricEncryptionPadding asymmetricEncryptionPadding, AsymmetricKeyParameter asymmetricKeyParameter, string encryptedInput) + { + + IAsymmetricBlockCipher asymEngine = getEngine(asymmetricEncryptionAlgorithm); + IDigest hash = getDigest(hashAlgorithm); + IAsymmetricBlockCipher cipher = getPadding(asymEngine, hash, asymmetricEncryptionPadding); + BufferedAsymmetricBlockCipher bufferedCipher = new BufferedAsymmetricBlockCipher(cipher); + if (this.error.existsError()) + { + return ""; + } + bufferedCipher.Init(false, asymmetricKeyParameter); + byte[] inputBytes = Base64.Decode(encryptedInput); + bufferedCipher.ProcessBytes(inputBytes, 0, inputBytes.Length); + byte[] outputBytes = bufferedCipher.DoFinal(); + if (outputBytes == null || outputBytes.Length == 0) + { + this.error.setError("AE040", "Asymmetric decryption error"); + return ""; + } + EncodingUtil eu = new EncodingUtil(); + this.error = eu.GetError(); + return eu.getString(outputBytes); + + + } + /// + /// Encrypts the string encoded plain text + /// + /// + /// + /// + /// + /// + /// Base64 encrypted encryptedInput text + private string doEncrypt(AsymmetricEncryptionAlgorithm asymmetricEncryptionAlgorithm, HashAlgorithm hashAlgorithm, AsymmetricEncryptionPadding asymmetricEncryptionPadding, AsymmetricKeyParameter asymmetricKeyParameter, string plainText) + { + IAsymmetricBlockCipher asymEngine = getEngine(asymmetricEncryptionAlgorithm); + IDigest hash = getDigest(hashAlgorithm); + IAsymmetricBlockCipher cipher = getPadding(asymEngine, hash, asymmetricEncryptionPadding); + BufferedAsymmetricBlockCipher bufferedCipher = new BufferedAsymmetricBlockCipher(cipher); + if (this.error.existsError()) + { + return ""; + } + bufferedCipher.Init(true, asymmetricKeyParameter); + EncodingUtil eu = new EncodingUtil(); + byte[] inputBytes = eu.getBytes(plainText); + if (eu.GetError().existsError()) + { + this.error = eu.GetError(); + return ""; + } + bufferedCipher.ProcessBytes(inputBytes, 0, inputBytes.Length); + byte[] outputBytes = bufferedCipher.DoFinal(); + if (outputBytes == null || outputBytes.Length == 0) + { + this.error.setError("AE041", "Asymmetric encryption error"); + return ""; + } + this.error.cleanError(); + return Base64.ToBase64String(outputBytes); + + } + /// + /// Build asymmetric block cipher engine + /// + /// AsymmetricEncryptionAlgorithm enum, algorithm name + /// IAsymmetricBlockCipher Engine for the specified algorithm + private IAsymmetricBlockCipher getEngine(AsymmetricEncryptionAlgorithm asymmetricEncryptionAlgorithm) + { + + switch (asymmetricEncryptionAlgorithm) + { + case AsymmetricEncryptionAlgorithm.RSA: + return new RsaEngine(); + default: + this.error.setError("AE042", "Unrecognized algorithm"); + return null; + } + + } + /// + /// Build Digest engine for asymmetric block cipher and signing + /// + /// HashAlgorithm enum, algorithm name + /// IDigest Engine for the specified algorithm + private IDigest getDigest(HashAlgorithm hashAlgorithm) + { + Hashing hash = new Hashing(); + IDigest digest = hash.createHash(hashAlgorithm); + if (digest == null) + { + this.error.setError("AE043", "Unrecognized HashAlgorithm"); + return null; + } + return digest; + } + /// + /// Buils Asymmetric Block Cipher engine + /// + /// AsymmetricBlockCipher enum, algorithm name + /// Digest Engine for hashing + /// AsymmetricEncryptionPadding enum, padding name + /// AsymmetricBlockCipher Engine specific for the algoritm, hash and padding + private IAsymmetricBlockCipher getPadding(IAsymmetricBlockCipher asymBlockCipher, IDigest hash, AsymmetricEncryptionPadding asymmetricEncryptionPadding) + { + switch (asymmetricEncryptionPadding) + { + case AsymmetricEncryptionPadding.NOPADDING: + return null; + case AsymmetricEncryptionPadding.OAEPPADDING: + if (hash != null) + { + return new OaepEncoding(asymBlockCipher, hash); + } + else + { + return new OaepEncoding(asymBlockCipher); + } + case AsymmetricEncryptionPadding.PCKS1PADDING: + return new Pkcs1Encoding(asymBlockCipher); + case AsymmetricEncryptionPadding.ISO97961PADDING: + return new ISO9796d1Encoding(asymBlockCipher); + default: + error.setError("AE044", "Unrecognized AsymmetricEncryptionPadding"); + return null; + } + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricSigner.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricSigner.cs index bae8ab4fe..5ec21efbb 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricSigner.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Asymmetric/AsymmetricSigner.cs @@ -36,23 +36,12 @@ public AsymmetricSigner() : base() [SecuritySafeCritical] public String DoSign(PrivateKeyManager key, string hashAlgorithm, string plainText) { - /******** INPUT VERIFICATION - BEGIN ********/ - if (key == null) - { - error.setError("AE001", "Private key cannot be null"); - return ""; - } - if (hashAlgorithm == null || hashAlgorithm.Length == 0 || SecurityUtils.compareStrings("", hashAlgorithm)) - { - error.setError("AE002", "HashAlgorithm cannot be empty value; use HashAlgorithm domain"); - return ""; - } - if (plainText == null || plainText.Length == 0 || SecurityUtils.compareStrings("", plainText)) - { - error.setError("AE003", "The plainText value to sign cannot be empty"); - return ""; - } - /******** INPUT VERIFICATION - END ********/ + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateObjectInput("key", key, this.error); + SecurityUtils.validateStringInput("hashAlgorithm", hashAlgorithm, this.error); + SecurityUtils.validateStringInput("plainText", plainText, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ EncodingUtil eu = new EncodingUtil(); @@ -73,23 +62,15 @@ public String DoSign(PrivateKeyManager key, string hashAlgorithm, string plainTe [SecuritySafeCritical] public String DoSignFile(PrivateKeyManager key, string hashAlgorithm, string path) { - /******** INPUT VERIFICATION - BEGIN ********/ - if (key == null) - { - error.setError("AE005", "Private key cannot be null"); - return ""; - } - if (hashAlgorithm == null || hashAlgorithm.Length == 0 || SecurityUtils.compareStrings("", hashAlgorithm)) - { - error.setError("AE006", "HashAlgorithm cannot be empty value; use HashAlgorithm domain"); - return ""; - } - if (path == null || path.Length == 0 || SecurityUtils.compareStrings("", path)) - { - error.setError("AE007", "The path value of the file to sign cannot be empty"); - return ""; - } - /******** INPUT VERIFICATION - END ********/ + this.error.cleanError(); + + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateObjectInput("key", key, this.error); + SecurityUtils.validateStringInput("hashAlgorithm", hashAlgorithm, this.error); + SecurityUtils.validateStringInput("path", path, this.error); + if (this.HasError()) { return ""; } + /*******INPUT VERIFICATION - END*******/ string result = ""; using (Stream input = SecurityUtils.getFileStream(path, this.error)) @@ -107,23 +88,14 @@ public String DoSignFile(PrivateKeyManager key, string hashAlgorithm, string pat [SecuritySafeCritical] public bool DoVerify(CertificateX509 cert, string plainText, string signature) { - /******** INPUT VERIFICATION - BEGIN ********/ - if (cert == null) - { - error.setError("AE009", "Certificate cannot be null"); - return false; - } - if (plainText == null || plainText.Length == 0 || SecurityUtils.compareStrings("", plainText)) - { - error.setError("AE010", "The plainText value to verify cannot be empty"); - return false; - } - if (signature == null || signature.Length == 0 || SecurityUtils.compareStrings("", signature)) - { - error.setError("AE011", "The signature value to verify cannot be empty"); - return false; - } - /******** INPUT VERIFICATION - END ********/ + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateObjectInput("cert", cert, this.error); + SecurityUtils.validateStringInput("plainText", plainText, this.error); + SecurityUtils.validateStringInput("signature", signature, this.error); + if (this.HasError()) { return false; } + /*******INPUT VERIFICATION - END*******/ EncodingUtil eu = new EncodingUtil(); @@ -144,23 +116,14 @@ public bool DoVerify(CertificateX509 cert, string plainText, string signature) [SecuritySafeCritical] public bool DoVerifyFile(CertificateX509 cert, string path, string signature) { - /******** INPUT VERIFICATION - BEGIN ********/ - if (cert == null) - { - error.setError("AE013", "Certificate cannot be null"); - return false; - } - if (path == null || path.Length == 0 || SecurityUtils.compareStrings("", path)) - { - error.setError("AE014", "The path value of the faile to verify cannot be empty"); - return false; - } - if (signature == null || signature.Length == 0 || SecurityUtils.compareStrings("", signature)) - { - error.setError("AE015", "The signature value to verify cannot be empty"); - return false; - } - /******** INPUT VERIFICATION - END ********/ + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateObjectInput("cert", cert, this.error); + SecurityUtils.validateStringInput("path", path, this.error); + SecurityUtils.validateStringInput("signature", signature, this.error); + if (this.HasError()) { return false; } + /*******INPUT VERIFICATION - END*******/ bool result = false; using (Stream input = SecurityUtils.getFileStream(path, this.error)) diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Checksum/ChecksumCreator.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Checksum/ChecksumCreator.cs index 21f7d1a96..a05e23fce 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Checksum/ChecksumCreator.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Checksum/ChecksumCreator.cs @@ -2,6 +2,7 @@ using GeneXusCryptography.Commons; using GeneXusCryptography.Hash; using GeneXusCryptography.HashUtils; +using Org.BouncyCastle.Utilities.Encoders; using SecurityAPICommons.Commons; using SecurityAPICommons.Utils; using System; @@ -12,7 +13,7 @@ namespace GeneXusCryptography.Checksum [SecuritySafeCritical] public class ChecksumCreator : SecurityAPIObject, IChecksumObject { - public ChecksumCreator(): base() + public ChecksumCreator() : base() { } @@ -21,6 +22,15 @@ public ChecksumCreator(): base() [SecuritySafeCritical] public string GenerateChecksum(string input, string inputType, string checksumAlgorithm) { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("input", input, this.error); + SecurityUtils.validateStringInput("inputType", inputType, this.error); + SecurityUtils.validateStringInput("checksumAlgorithm", checksumAlgorithm, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + ChecksumInputType chksumInputType = ChecksumInputTypeUtils.getChecksumInputType(inputType, this.error); byte[] inputBytes = ChecksumInputTypeUtils.getBytes(chksumInputType, input, this.error); if (this.HasError()) @@ -39,6 +49,16 @@ public string GenerateChecksum(string input, string inputType, string checksumAl [SecuritySafeCritical] public bool VerifyChecksum(string input, string inputType, string checksumAlgorithm, string digest) { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("input", input, this.error); + SecurityUtils.validateStringInput("inputType", inputType, this.error); + SecurityUtils.validateStringInput("checksumAlgorithm", checksumAlgorithm, this.error); + SecurityUtils.validateStringInput("digest", digest, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + if (digest == null) return false; string result = GenerateChecksum(input, inputType, checksumAlgorithm); if (SecurityUtils.compareStrings(result, "") || this.HasError()) @@ -78,19 +98,28 @@ private string CalculateCRC(byte[] input, ChecksumAlgorithm checksumAlgorithm) private string CalculateHash(byte[] input, ChecksumAlgorithm checksumAlgorithm) { - HashUtils.HashAlgorithm alg = getHashAlgorithm(checksumAlgorithm); + HashAlgorithm alg = getHashAlgorithm(checksumAlgorithm); if (this.HasError()) { return ""; } Hashing hash = new Hashing(); - byte[] digest = hash.calculateHash(alg, input); + byte[] digest = null; + try + { + digest = hash.CalculateHash(alg, input); + } + catch (Exception e) + { + error.setError("CH001", e.Message); + return ""; + } if (hash.HasError()) { this.error = hash.GetError(); return ""; } - return toHexaString(digest); + return Hex.ToHexString(digest); } private HashUtils.HashAlgorithm getHashAlgorithm(ChecksumAlgorithm checksumAlgorithm) @@ -98,17 +127,6 @@ private HashUtils.HashAlgorithm getHashAlgorithm(ChecksumAlgorithm checksumAlgor return HashAlgorithmUtils.getHashAlgorithm(ChecksumAlgorithmUtils.valueOf(checksumAlgorithm, this.error), this.error); } - private string toHexaString(byte[] digest) - { - string result = BitConverter.ToString(digest).Replace("-", string.Empty); - if (result == null || result.Length == 0) - { - this.error.setError("HS001", "Error encoding hexa"); - return ""; - } - return result.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim(); - } - private static long CalculateCRC(byte[] input, CRCParameters parms) { long curValue = parms.Init; diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/CRCParameters.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/CRCParameters.cs index 6fea42a69..eaabed22c 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/CRCParameters.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/CRCParameters.cs @@ -8,48 +8,48 @@ namespace GeneXusCryptography.ChecksumUtils public struct CRCParameters #pragma warning restore CA1815 // Override equals and operator equals on value types { - private int _width; - public int Width - { - get => _width; - } - private long _polynomial; - public long Polynomial - { - get => _polynomial; - } - private bool _reflectIn; - public bool ReflectIn - { - get => _reflectIn; - } - private bool _reflectOut; - public bool ReflectOut - { - get => _reflectOut; - } - private long _init; - public long Init - { - get => _init; - } - private long _finalXor; - public long FinalXor - { - get => _finalXor; + private int _width; + public int Width + { + get => _width; + } + private long _polynomial; + public long Polynomial + { + get => _polynomial; + } + private bool _reflectIn; + public bool ReflectIn + { + get => _reflectIn; + } + private bool _reflectOut; + public bool ReflectOut + { + get => _reflectOut; + } + private long _init; + public long Init + { + get => _init; + } + private long _finalXor; + public long FinalXor + { + get => _finalXor; - } + } - [SecuritySafeCritical] - public CRCParameters(int width, long polynomial, long init, bool reflectIn, bool reflectOut, long finalXor) - { - _width = width; - _polynomial = polynomial; - _reflectIn = reflectIn; - _reflectOut = reflectOut; - _init = init; - _finalXor = finalXor; - } + [SecuritySafeCritical] + public CRCParameters(int width, long polynomial, long init, bool reflectIn, bool reflectOut, long finalXor) + { + _width = width; + _polynomial = polynomial; + _reflectIn = reflectIn; + _reflectOut = reflectOut; + _init = init; + _finalXor = finalXor; + } - } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumAlgorithm.cs index 71c95588b..5f34760c6 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumAlgorithm.cs @@ -20,13 +20,13 @@ public enum ChecksumAlgorithm [SecuritySafeCritical] public static class ChecksumAlgorithmUtils { - + public static ChecksumAlgorithm getChecksumAlgorithm(string checksumAlgorithm, Error error) { - if(error == null) return ChecksumAlgorithm.NONE; + if (error == null) return ChecksumAlgorithm.NONE; if (checksumAlgorithm == null) { - error.setError("CA001", "Unrecognized checksum algorithm"); + error.setError("CHA04", "Unrecognized checksum algorithm"); return ChecksumAlgorithm.NONE; } switch (checksumAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) @@ -124,7 +124,7 @@ public static ChecksumAlgorithm getChecksumAlgorithm(string checksumAlgorithm, E case "SHA512": return ChecksumAlgorithm.SHA512; default: - error.setError("CA001", "Unrecognized checksum algorithm"); + error.setError("CHA01", "Unrecognized checksum algorithm"); return ChecksumAlgorithm.NONE; } } @@ -228,7 +228,7 @@ public static string valueOf(ChecksumAlgorithm checksumAlgorithm, Error error) case ChecksumAlgorithm.SHA512: return "SHA512"; default: - error.setError("CA002", "Unrecognized checksum algorithm"); + error.setError("CHA02", "Unrecognized checksum algorithm"); return null; } } @@ -337,7 +337,7 @@ public static CRCParameters getParameters(ChecksumAlgorithm checksumAlgorithm, E case ChecksumAlgorithm.CRC32_XFER: return new CRCParameters(32, 0x000000AF, 0x00000000, false, false, 0x0000000); default: - error.setError("CA004", "Unrecognized checksum algorithm"); + error.setError("CHA03", "Unrecognized checksum algorithm"); return new CRCParameters(0, 0x00, 0x00, false, false, 0x00); } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumInputType.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumInputType.cs index afe66bd66..7e4563c32 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumInputType.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/ChecksumUtils/ChecksumInputType.cs @@ -21,10 +21,10 @@ public static class ChecksumInputTypeUtils { public static ChecksumInputType getChecksumInputType(string checksumInputType, Error error) { - if(error == null) return ChecksumInputType.NONE; + if (error == null) return ChecksumInputType.NONE; if (checksumInputType == null) { - error.setError("CI001", "Unrecognized checksum input type"); + error.setError("CHI06", "Unrecognized checksum input type"); return ChecksumInputType.NONE; } switch (checksumInputType.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) @@ -40,7 +40,7 @@ public static ChecksumInputType getChecksumInputType(string checksumInputType, E case "LOCAL_FILE": return ChecksumInputType.LOCAL_FILE; default: - error.setError("CI001", "Unrecognized checksum input type"); + error.setError("CHI01", "Unrecognized checksum input type"); return ChecksumInputType.NONE; } } @@ -61,7 +61,7 @@ public static string valueOf(ChecksumInputType checksumInputType, Error error) case ChecksumInputType.LOCAL_FILE: return "LOCAL_FILE"; default: - error.setError("CI002", "Unrecognized checksum input type"); + error.setError("CHI02", "Unrecognized checksum input type"); return ""; } } @@ -80,11 +80,11 @@ public static byte[] getBytes(ChecksumInputType checksumInputType, string input, } catch (Exception e) { - error.setError("CI003", e.Message); + error.setError("CHI03", e.Message); } break; case ChecksumInputType.HEX: - aux = SecurityUtils.GetHexa(input, "CI004", error); + aux = SecurityUtils.HexaToByte(input, error); break; case ChecksumInputType.TXT: aux = eu.getBytes(input); @@ -100,14 +100,14 @@ public static byte[] getBytes(ChecksumInputType checksumInputType, string input, } catch (Exception e) { - error.setError("CI004", e.Message); + error.setError("CHI04", e.Message); } break; case ChecksumInputType.LOCAL_FILE: aux = SecurityUtils.getFileBytes(input, error); break; default: - error.setError("CI006", "Unrecognized checksum input type"); + error.setError("CHI05", "Unrecognized checksum input type"); break; } return aux; diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Hash/Hashing.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Hash/Hashing.cs index 342b69acd..4f1b8f9d7 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Hash/Hashing.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Hash/Hashing.cs @@ -7,197 +7,181 @@ using Org.BouncyCastle.Crypto.Digests; using System; using System.Security; - +using SecurityAPICommons.Utils; +using Org.BouncyCastle.Utilities.Encoders; +using System.IO; namespace GeneXusCryptography.Hash { - /// - /// Implements hashing engines to calculate string digests - /// - [SecuritySafeCritical] - public class Hashing : SecurityAPIObject, IHashObject - { - - /// - /// Hashing constructor - /// - public Hashing() : base() - { - - } - - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - - - - /// - /// Calculate the hash digest with the given algorithm - /// - /// string HashAlgorithm enum, algorithm name - /// plain text to hcalculate hash - /// string Hexa representation of the txtToHash with the algorithm indicated - [SecuritySafeCritical] - public string DoHash(string hashAlgorithm, string txtToHash) - { - this.error.cleanError(); - HashAlgorithm hash = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error); - - byte[] resBytes = calculateHash(hash, txtToHash); - string result = toHexaString(resBytes); - if (!this.error.existsError()) - { - return result; - } - return ""; - } - - - - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - /// - /// Gets the hexadecimal encoded representation of the digest input - /// - /// byte array - /// string Hexa respresentation of the byte array digest - private string toHexaString(byte[] digest) - { - string result = BitConverter.ToString(digest).Replace("-", string.Empty); - if (result == null || result.Length == 0) - { - this.error.setError("HS001", "Error encoding hexa"); - return ""; - } - return result; - } - - /// - /// Calculate the hash digest with the given algorithm - /// - /// HashAlgorithm enum, algorithm name - /// plain text to hcalculate hash - /// byte array of the txtToHash with the algorithm indicated - private byte[] calculateHash(HashAlgorithm hashAlgorithm, string txtToHash) - { - if (this.error.existsError()) - { - return null; - } - EncodingUtil eu = new EncodingUtil(); - byte[] inputAsBytes = eu.getBytes(txtToHash); - if (eu.GetError().existsError()) - { - this.error = eu.GetError(); - return null; - } - return calculateHash(hashAlgorithm, inputAsBytes); - } - - [SecuritySafeCritical] - public byte[] calculateHash(HashAlgorithm hashAlgorithm, byte[] inputAsBytes) - { - IDigest alg = createHash(hashAlgorithm); - if (alg == null) - { - return null; - } - byte[] retValue = new byte[alg.GetDigestSize()]; - if (inputAsBytes != null) - { - alg.BlockUpdate(inputAsBytes, 0, inputAsBytes.Length); - } - alg.DoFinal(retValue, 0); - return retValue; - } - - /// - /// Build the hash engine - /// - /// HashAlgorithm enum, algorithm name - /// IDigest algorithm instantiated class - internal IDigest createHash(HashAlgorithm hashAlgorithm) - { - switch (hashAlgorithm) - { - case HashAlgorithm.MD5: - return new MD5Digest(); - case HashAlgorithm.SHA1: - return new Sha1Digest(); - case HashAlgorithm.SHA224: - return new Sha224Digest(); - case HashAlgorithm.SHA256: - return new Sha256Digest(); - case HashAlgorithm.SHA384: - return new Sha384Digest(); - case HashAlgorithm.SHA512: - return new Sha512Digest(); - case HashAlgorithm.BLAKE2B_224: - return new Blake2bDigest(224); - case HashAlgorithm.BLAKE2B_256: - return new Blake2bDigest(256); - case HashAlgorithm.BLAKE2B_384: - return new Blake2bDigest(384); - case HashAlgorithm.BLAKE2B_512: - return new Blake2bDigest(512); - case HashAlgorithm.BLAKE2S_128: - return new Blake2sDigest(128); - case HashAlgorithm.BLAKE2S_160: - return new Blake2sDigest(160); - case HashAlgorithm.BLAKE2S_224: - return new Blake2sDigest(224); - case HashAlgorithm.BLAKE2S_256: - return new Blake2sDigest(256); - case HashAlgorithm.GOST3411_2012_256: - return new Gost3411_2012_256Digest(); - case HashAlgorithm.GOST3411_2012_512: - return new Gost3411_2012_512Digest(); - case HashAlgorithm.GOST3411: - return new Gost3411Digest(); - case HashAlgorithm.KECCAK_224: - return new KeccakDigest(224); - case HashAlgorithm.KECCAK_256: - return new KeccakDigest(256); - case HashAlgorithm.KECCAK_288: - return new KeccakDigest(288); - case HashAlgorithm.KECCAK_384: - return new KeccakDigest(384); - case HashAlgorithm.KECCAK_512: - return new KeccakDigest(512); - case HashAlgorithm.MD2: - return new MD2Digest(); - case HashAlgorithm.MD4: - return new MD4Digest(); - case HashAlgorithm.RIPEMD128: - return new RipeMD128Digest(); - case HashAlgorithm.RIPEMD160: - return new RipeMD160Digest(); - case HashAlgorithm.RIPEMD256: - return new RipeMD256Digest(); - case HashAlgorithm.RIPEMD320: - return new RipeMD320Digest(); - case HashAlgorithm.SHA3_224: - return new Sha3Digest(224); - case HashAlgorithm.SHA3_256: - return new Sha3Digest(256); - case HashAlgorithm.SHA3_384: - return new Sha3Digest(384); - case HashAlgorithm.SHA3_512: - return new Sha3Digest(512); - /*case HashAlgorithm.SHAKE_128: - return new ShakeDigest(128); - case HashAlgorithm.SHAKE_256: - return new ShakeDigest(256);*/ - case HashAlgorithm.SM3: - return new SM3Digest(); - case HashAlgorithm.TIGER: - return new TigerDigest(); - case HashAlgorithm.WHIRLPOOL: - return new WhirlpoolDigest(); - default: - this.error.setError("HS002", "Unrecognized HashAlgorithm"); - return null; - } - } - - } + /// + /// Implements hashing engines to calculate string digests + /// + [SecuritySafeCritical] + public class Hashing : SecurityAPIObject, IHashObject + { + + /// + /// Hashing constructor + /// + public Hashing() : base() + { + + } + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + + + /// + /// Calculate the hash digest with the given algorithm + /// + /// string HashAlgorithm enum, algorithm name + /// plain text to hcalculate hash + /// string Hexa representation of the txtToHash with the algorithm indicated + [SecuritySafeCritical] + public string DoHash(string hashAlgorithm, string txtToHash) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("hashAlgorithm", hashAlgorithm, this.error); + SecurityUtils.validateStringInput("txtToHash", txtToHash, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + HashAlgorithm hashAlgorithmObj = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error); + EncodingUtil eu = new EncodingUtil(); + byte[] input = eu.getBytes(txtToHash); + if (eu.HasError()) + { + this.error = eu.GetError(); + } + if (this.HasError()) { return null; } + + byte[] resBytes = CalculateHash(hashAlgorithmObj, input); + + return this.HasError() ? "" : Hex.ToHexString(resBytes).ToUpper(); + } + + + + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + [SecuritySafeCritical] + public byte[] CalculateHash(HashAlgorithm hashAlgorithm, byte[] input) + { + IDigest alg = createHash(hashAlgorithm); + byte[] buffer = new byte[8192]; + int n; + byte[] retValue = new byte[alg.GetDigestSize()]; + try + { + using (Stream inputStream = new MemoryStream(input)) + { + while ((n = inputStream.Read(buffer, 0, buffer.Length)) > 0) + { + alg.BlockUpdate(buffer, 0, n); + } + } + alg.DoFinal(retValue, 0); + + } + catch (Exception e) + { + error.setError("HA001", e.Message); + return null; + } + return retValue; + } + + + + + + /// + /// Build the hash engine + /// + /// HashAlgorithm enum, algorithm name + /// IDigest algorithm instantiated class + internal IDigest createHash(HashAlgorithm hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.MD5: + return new MD5Digest(); + case HashAlgorithm.SHA1: + return new Sha1Digest(); + case HashAlgorithm.SHA224: + return new Sha224Digest(); + case HashAlgorithm.SHA256: + return new Sha256Digest(); + case HashAlgorithm.SHA384: + return new Sha384Digest(); + case HashAlgorithm.SHA512: + return new Sha512Digest(); + case HashAlgorithm.BLAKE2B_224: + return new Blake2bDigest(224); + case HashAlgorithm.BLAKE2B_256: + return new Blake2bDigest(256); + case HashAlgorithm.BLAKE2B_384: + return new Blake2bDigest(384); + case HashAlgorithm.BLAKE2B_512: + return new Blake2bDigest(512); + case HashAlgorithm.BLAKE2S_128: + return new Blake2sDigest(128); + case HashAlgorithm.BLAKE2S_160: + return new Blake2sDigest(160); + case HashAlgorithm.BLAKE2S_224: + return new Blake2sDigest(224); + case HashAlgorithm.BLAKE2S_256: + return new Blake2sDigest(256); + case HashAlgorithm.GOST3411_2012_256: + return new Gost3411_2012_256Digest(); + case HashAlgorithm.GOST3411_2012_512: + return new Gost3411_2012_512Digest(); + case HashAlgorithm.GOST3411: + return new Gost3411Digest(); + case HashAlgorithm.KECCAK_224: + return new KeccakDigest(224); + case HashAlgorithm.KECCAK_256: + return new KeccakDigest(256); + case HashAlgorithm.KECCAK_288: + return new KeccakDigest(288); + case HashAlgorithm.KECCAK_384: + return new KeccakDigest(384); + case HashAlgorithm.KECCAK_512: + return new KeccakDigest(512); + case HashAlgorithm.MD2: + return new MD2Digest(); + case HashAlgorithm.MD4: + return new MD4Digest(); + case HashAlgorithm.RIPEMD128: + return new RipeMD128Digest(); + case HashAlgorithm.RIPEMD160: + return new RipeMD160Digest(); + case HashAlgorithm.RIPEMD256: + return new RipeMD256Digest(); + case HashAlgorithm.RIPEMD320: + return new RipeMD320Digest(); + case HashAlgorithm.SHA3_224: + return new Sha3Digest(224); + case HashAlgorithm.SHA3_256: + return new Sha3Digest(256); + case HashAlgorithm.SHA3_384: + return new Sha3Digest(384); + case HashAlgorithm.SHA3_512: + return new Sha3Digest(512); + case HashAlgorithm.SM3: + return new SM3Digest(); + case HashAlgorithm.TIGER: + return new TigerDigest(); + case HashAlgorithm.WHIRLPOOL: + return new WhirlpoolDigest(); + default: + this.error.setError("HA002", "Unrecognized HashAlgorithm"); + return null; + } + } + + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/HashUtils/HashAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/HashUtils/HashAlgorithm.cs index 705c7a4f6..8f605451e 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/HashUtils/HashAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/HashUtils/HashAlgorithm.cs @@ -9,12 +9,12 @@ namespace GeneXusCryptography.HashUtils { - /// - /// Implements HashAlgorithm enumerated - /// - [SecuritySafeCritical] - public enum HashAlgorithm - { + /// + /// Implements HashAlgorithm enumerated + /// + [SecuritySafeCritical] + public enum HashAlgorithm + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #pragma warning disable CA1707 // Identifiers should not contain underscores @@ -22,212 +22,210 @@ public enum HashAlgorithm #pragma warning restore CA1707 // Identifiers should not contain underscores #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } - /// - /// Implements HashAlgorithm associated functions - /// - [SecuritySafeCritical] - public static class HashAlgorithmUtils - { + /// + /// Implements HashAlgorithm associated functions + /// + [SecuritySafeCritical] + public static class HashAlgorithmUtils + { - /// - /// Mapping between string name and HashAlgorithm enum representation - /// - /// string hashAlgorithm - /// Error type for error management - /// HashAlgorithm enum representation - public static HashAlgorithm getHashAlgorithm(string hashAlgorithm, Error error) + /// + /// Mapping between string name and HashAlgorithm enum representation + /// + /// string hashAlgorithm + /// Error type for error management + /// HashAlgorithm enum representation + public static HashAlgorithm getHashAlgorithm(string hashAlgorithm, Error error) { - if(error == null) return HashAlgorithm.NONE; + if (error == null) return HashAlgorithm.NONE; if (hashAlgorithm == null) { - error.setError("HA001", "Unrecognized HashAlgorihm"); + error.setError("HAA01", "Unrecognized HashAlgorihm"); return HashAlgorithm.NONE; } - switch (hashAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "MD5": - return HashAlgorithm.MD5; - case "SHA1": - return HashAlgorithm.SHA1; - case "SHA224": - return HashAlgorithm.SHA224; - case "SHA256": - return HashAlgorithm.SHA256; - case "SHA384": - return HashAlgorithm.SHA384; - case "SHA512": - return HashAlgorithm.SHA512; - case "BLAKE2B_224": - return HashAlgorithm.BLAKE2B_224; - case "BLAKE2B_256": - return HashAlgorithm.BLAKE2B_256; - case "BLAKE2B_384": - return HashAlgorithm.BLAKE2B_384; - case "BLAKE2B_512": - return HashAlgorithm.BLAKE2B_512; - case "BLAKE2S_128": - return HashAlgorithm.BLAKE2S_128; - case "BLAKE2S_160": - return HashAlgorithm.BLAKE2S_160; - case "BLAKE2S_224": - return HashAlgorithm.BLAKE2S_224; - case "BLAKE2S_256": - return HashAlgorithm.BLAKE2S_256; - case "GOST3411_2012_256": - return HashAlgorithm.GOST3411_2012_256; - case "GOST3411_2012_512": - return HashAlgorithm.GOST3411_2012_512; - case "GOST3411": - return HashAlgorithm.GOST3411; - case "KECCAK_224": - return HashAlgorithm.KECCAK_224; - case "KECCAK_256": - return HashAlgorithm.KECCAK_256; - case "KECCAK_288": - return HashAlgorithm.KECCAK_288; - case "KECCAK_384": - return HashAlgorithm.KECCAK_384; - case "KECCAK_512": - return HashAlgorithm.KECCAK_512; - case "MD2": - return HashAlgorithm.MD2; - case "MD4": - return HashAlgorithm.MD4; - case "RIPEMD128": - return HashAlgorithm.RIPEMD128; - case "RIPEMD160": - return HashAlgorithm.RIPEMD160; - case "RIPEMD256": - return HashAlgorithm.RIPEMD256; - case "RIPEMD320": - return HashAlgorithm.RIPEMD320; - case "SHA3-224": - return HashAlgorithm.SHA3_224; - case "SHA3-256": - return HashAlgorithm.SHA3_256; - case "SHA3-384": - return HashAlgorithm.SHA3_384; - case "SHA3-512": - return HashAlgorithm.SHA3_512; - case "SHAKE_128": - error.setError("HA003", "Not implemented algorithm SHAKE_128"); + switch (hashAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) + { + case "MD5": + return HashAlgorithm.MD5; + case "SHA1": + return HashAlgorithm.SHA1; + case "SHA224": + return HashAlgorithm.SHA224; + case "SHA256": + return HashAlgorithm.SHA256; + case "SHA384": + return HashAlgorithm.SHA384; + case "SHA512": + return HashAlgorithm.SHA512; + case "BLAKE2B_224": + return HashAlgorithm.BLAKE2B_224; + case "BLAKE2B_256": + return HashAlgorithm.BLAKE2B_256; + case "BLAKE2B_384": + return HashAlgorithm.BLAKE2B_384; + case "BLAKE2B_512": + return HashAlgorithm.BLAKE2B_512; + case "BLAKE2S_128": + return HashAlgorithm.BLAKE2S_128; + case "BLAKE2S_160": + return HashAlgorithm.BLAKE2S_160; + case "BLAKE2S_224": + return HashAlgorithm.BLAKE2S_224; + case "BLAKE2S_256": + return HashAlgorithm.BLAKE2S_256; + case "GOST3411_2012_256": + return HashAlgorithm.GOST3411_2012_256; + case "GOST3411_2012_512": + return HashAlgorithm.GOST3411_2012_512; + case "GOST3411": + return HashAlgorithm.GOST3411; + case "KECCAK_224": + return HashAlgorithm.KECCAK_224; + case "KECCAK_256": + return HashAlgorithm.KECCAK_256; + case "KECCAK_288": + return HashAlgorithm.KECCAK_288; + case "KECCAK_384": + return HashAlgorithm.KECCAK_384; + case "KECCAK_512": + return HashAlgorithm.KECCAK_512; + case "MD2": + return HashAlgorithm.MD2; + case "MD4": + return HashAlgorithm.MD4; + case "RIPEMD128": + return HashAlgorithm.RIPEMD128; + case "RIPEMD160": + return HashAlgorithm.RIPEMD160; + case "RIPEMD256": + return HashAlgorithm.RIPEMD256; + case "RIPEMD320": + return HashAlgorithm.RIPEMD320; + case "SHA3-224": + return HashAlgorithm.SHA3_224; + case "SHA3-256": + return HashAlgorithm.SHA3_256; + case "SHA3-384": + return HashAlgorithm.SHA3_384; + case "SHA3-512": + return HashAlgorithm.SHA3_512; + case "SHAKE_128": + error.setError("HAA04", "Not implemented algorithm SHAKE_128"); return HashAlgorithm.NONE; - //return HashAlgorithm.SHAKE_128; case "SHAKE_256": - error.setError("HA004", "Not implemented algorithm SHAKE_256"); + error.setError("HAA05", "Not implemented algorithm SHAKE_256"); return HashAlgorithm.NONE; - // return HashAlgorithm.SHAKE_256; case "SM3": - return HashAlgorithm.SM3; - case "TIGER": - return HashAlgorithm.TIGER; - case "WHIRLPOOL": - return HashAlgorithm.WHIRLPOOL; - default: - error.setError("HA001", "Unrecognized HashAlgorihm"); - return HashAlgorithm.NONE; - } - } + return HashAlgorithm.SM3; + case "TIGER": + return HashAlgorithm.TIGER; + case "WHIRLPOOL": + return HashAlgorithm.WHIRLPOOL; + default: + error.setError("HAA02", "Unrecognized HashAlgorihm"); + return HashAlgorithm.NONE; + } + } - /// - /// Mapping between HashAlgorithm enum representation and string name - /// - /// HashAlgorithm enum, algorithm name - /// Error type for error management - /// string name value of HashAlgorithm - public static string valueOf(HashAlgorithm hashAlgorithm, Error error) - { - if(error == null) return "Unrecognized algorithm"; + /// + /// Mapping between HashAlgorithm enum representation and string name + /// + /// HashAlgorithm enum, algorithm name + /// Error type for error management + /// string name value of HashAlgorithm + public static string valueOf(HashAlgorithm hashAlgorithm, Error error) + { + if (error == null) return "Unrecognized algorithm"; switch (hashAlgorithm) - { - case HashAlgorithm.MD5: - return "MD5"; - case HashAlgorithm.SHA1: - return "SHA1"; - case HashAlgorithm.SHA224: - return "SHA224"; - case HashAlgorithm.SHA256: - return "SHA256"; - case HashAlgorithm.SHA384: - return "SHA384"; - case HashAlgorithm.SHA512: - return "SHA512"; - case HashAlgorithm.BLAKE2B_224: - return "BLAKE2B_224"; - case HashAlgorithm.BLAKE2B_256: - return "BLAKE2B_256"; - case HashAlgorithm.BLAKE2B_384: - return "BLAKE2B_384"; - case HashAlgorithm.BLAKE2B_512: - return "BLAKE2B_512"; - case HashAlgorithm.BLAKE2S_128: - return "BLAKE2S_128"; - case HashAlgorithm.BLAKE2S_160: - return "BLAKE2S_160"; - case HashAlgorithm.BLAKE2S_224: - return "BLAKE2S_224"; - case HashAlgorithm.BLAKE2S_256: - return "BLAKE2S_256"; - case HashAlgorithm.GOST3411_2012_256: - return "GOST3411_2012_256"; - case HashAlgorithm.GOST3411_2012_512: - return "GOST3411_2012_512"; - case HashAlgorithm.GOST3411: - return "GOST3411"; - case HashAlgorithm.KECCAK_224: - return "KECCAK_224"; - case HashAlgorithm.KECCAK_256: - return "KECCAK_256"; - case HashAlgorithm.KECCAK_288: - return "KECCAK_288"; - case HashAlgorithm.KECCAK_384: - return "KECCAK_384"; - case HashAlgorithm.KECCAK_512: - return "KECCAK_512"; - case HashAlgorithm.MD2: - return "MD2"; - case HashAlgorithm.MD4: - return "MD4"; - case HashAlgorithm.RIPEMD128: - return "RIPEMD128"; - case HashAlgorithm.RIPEMD160: - return "RIPEMD160"; - case HashAlgorithm.RIPEMD256: - return "RIPEMD256"; - case HashAlgorithm.RIPEMD320: - return "RIPEMD320"; - case HashAlgorithm.SHA3_224: - return "SHA3_224"; - case HashAlgorithm.SHA3_256: - return "SHA3_256"; - case HashAlgorithm.SHA3_384: - return "SHA3_384"; - case HashAlgorithm.SHA3_512: - return "SHA3_512"; - /* case HashAlgorithm.SHAKE_128: - return "SHAKE_128"; - case HashAlgorithm.SHAKE_256: - return "SHAKE_256";*/ - case HashAlgorithm.SM3: - return "SM3"; - case HashAlgorithm.TIGER: - return "TIGER"; - case HashAlgorithm.WHIRLPOOL: - return "WHIRLPOOL"; - default: - error.setError("HA002", "Unrecognized HashAlgorihm"); - return "Unrecognized algorithm"; - } - } + { + case HashAlgorithm.MD5: + return "MD5"; + case HashAlgorithm.SHA1: + return "SHA1"; + case HashAlgorithm.SHA224: + return "SHA224"; + case HashAlgorithm.SHA256: + return "SHA256"; + case HashAlgorithm.SHA384: + return "SHA384"; + case HashAlgorithm.SHA512: + return "SHA512"; + case HashAlgorithm.BLAKE2B_224: + return "BLAKE2B_224"; + case HashAlgorithm.BLAKE2B_256: + return "BLAKE2B_256"; + case HashAlgorithm.BLAKE2B_384: + return "BLAKE2B_384"; + case HashAlgorithm.BLAKE2B_512: + return "BLAKE2B_512"; + case HashAlgorithm.BLAKE2S_128: + return "BLAKE2S_128"; + case HashAlgorithm.BLAKE2S_160: + return "BLAKE2S_160"; + case HashAlgorithm.BLAKE2S_224: + return "BLAKE2S_224"; + case HashAlgorithm.BLAKE2S_256: + return "BLAKE2S_256"; + case HashAlgorithm.GOST3411_2012_256: + return "GOST3411_2012_256"; + case HashAlgorithm.GOST3411_2012_512: + return "GOST3411_2012_512"; + case HashAlgorithm.GOST3411: + return "GOST3411"; + case HashAlgorithm.KECCAK_224: + return "KECCAK_224"; + case HashAlgorithm.KECCAK_256: + return "KECCAK_256"; + case HashAlgorithm.KECCAK_288: + return "KECCAK_288"; + case HashAlgorithm.KECCAK_384: + return "KECCAK_384"; + case HashAlgorithm.KECCAK_512: + return "KECCAK_512"; + case HashAlgorithm.MD2: + return "MD2"; + case HashAlgorithm.MD4: + return "MD4"; + case HashAlgorithm.RIPEMD128: + return "RIPEMD128"; + case HashAlgorithm.RIPEMD160: + return "RIPEMD160"; + case HashAlgorithm.RIPEMD256: + return "RIPEMD256"; + case HashAlgorithm.RIPEMD320: + return "RIPEMD320"; + case HashAlgorithm.SHA3_224: + return "SHA3_224"; + case HashAlgorithm.SHA3_256: + return "SHA3_256"; + case HashAlgorithm.SHA3_384: + return "SHA3_384"; + case HashAlgorithm.SHA3_512: + return "SHA3_512"; + case HashAlgorithm.SHAKE_128: + return "SHAKE_128"; + case HashAlgorithm.SHAKE_256: + return "SHAKE_256"; + case HashAlgorithm.SM3: + return "SM3"; + case HashAlgorithm.TIGER: + return "TIGER"; + case HashAlgorithm.WHIRLPOOL: + return "WHIRLPOOL"; + default: + error.setError("HAA03", "Unrecognized HashAlgorihm"); + return "Unrecognized algorithm"; + } + } - /// - /// Manage Enumerable enum - /// - /// HashAlgorithm enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(HashAlgorithm)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// HashAlgorithm enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(HashAlgorithm)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Cmac.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Cmac.cs index 45743fda9..49cb4582b 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Cmac.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Cmac.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; using System.Security; using SecurityAPICommons.Commons; using GeneXusCryptography.Commons; @@ -14,126 +10,139 @@ using SecurityAPICommons.Config; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Macs; +using System.IO; namespace GeneXusCryptography.Mac { - [SecuritySafeCritical] - public class Cmac : SecurityAPIObject, ICmacObject - { - public Cmac() : base() - { - - } - - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - - - [SecuritySafeCritical] - public string calculate(string plainText, string key, string algorithm, int macSize) - { - if (!isValidAlgorithm(algorithm)) - { - this.error.setError("CM001", "Invalid Symmetric block algorithm for CMAC"); - return ""; - } - SymmetricBlockAlgorithm symmetricBlockAlgorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(algorithm, - this.error); - SymmetricBlockCipher symCipher = new SymmetricBlockCipher(); - IBlockCipher blockCipher = symCipher.getCipherEngine(symmetricBlockAlgorithm); - if (symCipher.HasError()) - { - this.error = symCipher.GetError(); - return ""; - } - if (macSize > blockCipher.GetBlockSize() * 8) - { - this.error.setError("CM002", "The mac length must be less or equal than the algorithm block size."); - return ""; - } - byte[] byteKey = SecurityUtils.GetHexa(key, "CM003", this.error); - if (this.HasError()) + [SecuritySafeCritical] + public class Cmac : SecurityAPIObject, ICmacObject + { + public Cmac() : base() + { + + } + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + + [SecuritySafeCritical] + public string calculate(string plainText, string key, string algorithm, int macSize) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("plainText", plainText, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("algorithm", algorithm, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + + SymmetricBlockAlgorithm symmetricBlockAlgorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(algorithm, + this.error); + + byte[] byteKey = SecurityUtils.HexaToByte(key, this.error); + if (this.HasError()) { return ""; } + + SymmetricBlockCipher symCipher = new SymmetricBlockCipher(); + IBlockCipher blockCipher = symCipher.getCipherEngine(symmetricBlockAlgorithm); + + if (symCipher.HasError()) + { + this.error = symCipher.GetError(); + return ""; + } + + + int blockSize = blockCipher.GetBlockSize() * 8; + + if (macSize > blockSize) + { + this.error.setError("CM001", "The mac length must be less or equal than the algorithm block size."); + return ""; + } + + if (blockSize != 64 && blockSize != 128) { + this.error.setError("CM002", "The block size must be 64 or 128 bits for CMAC. Wrong symmetric algorithm"); return ""; } - - EncodingUtil eu = new EncodingUtil(); - byte[] byteInput = eu.getBytes(plainText); - - ICipherParameters parms = new KeyParameter(byteKey); - - CMac mac = null; - if (macSize != 0) - { - mac = new CMac(blockCipher, macSize); - } - else - { - mac = new CMac(blockCipher); - } + EncodingUtil eu = new EncodingUtil(); + byte[] inputText = eu.getBytes(plainText); + if (eu.HasError()) + { + error = eu.GetError(); + return null; + } + byte[] resBytes = null; + using (Stream inputStream = new MemoryStream(inputText)) + { + resBytes = calculate(inputStream, byteKey, macSize, blockCipher); + } + + + return this.HasError() ? "" : Hex.ToHexString(resBytes); + + } + + + [SecuritySafeCritical] + public bool verify(string plainText, string key, string mac, string algorithm, int macSize) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("plainText", plainText, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("mac", mac, this.error); + SecurityUtils.validateStringInput("algorithm", algorithm, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + + string res = calculate(plainText, key, algorithm, macSize); + return SecurityUtils.compareStrings(res, mac); + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + + private byte[] calculate(Stream input, byte[] key, int macSize, IBlockCipher blockCipher) + { + ICipherParameters parms = new KeyParameter(key); + + CMac mac = macSize != 0 ? new CMac(blockCipher, macSize) : new CMac(blockCipher); + try { mac.Init(parms); - }catch(Exception e) + } + catch (Exception e) + { + this.error.setError("CM003", e.Message); + return null; + } + + byte[] buffer = new byte[8192]; + int n; + byte[] retValue = new byte[mac.GetMacSize()]; + try { + while ((n = input.Read(buffer, 0, buffer.Length)) > 0) + { + mac.BlockUpdate(buffer, 0, n); + } + mac.DoFinal(retValue, 0); + } + catch (Exception e) + { + this.error.setError("CM004", e.Message); - return ""; + return null; } - byte[] resBytes = new byte[mac.GetMacSize()]; - mac.BlockUpdate(byteInput, 0, byteInput.Length); - mac.DoFinal(resBytes, 0); - string result = toHexastring(resBytes); - if (!this.error.existsError()) - { - return result; - } - return ""; - - } - - - [SecuritySafeCritical] - public bool verify(string plainText, string key, string mac, string algorithm, int macSize) - { - string res = calculate(plainText, key, algorithm, macSize); - return SecurityUtils.compareStrings(res, mac); - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - /// - /// Gets the hexadecimal encoded representation of the digest input - /// - /// byte array - /// string Hexa respresentation of the byte array digest - private string toHexastring(byte[] digest) - { - string result = BitConverter.ToString(digest).Replace("-", string.Empty); - if (result == null || result.Length == 0) - { - this.error.setError("HS001", "Error encoding hexa"); - return ""; - } - return result; - } - - private bool isValidAlgorithm(string algorithm) - { - SymmetricBlockAlgorithm symmetricBlockAlgorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(algorithm, - this.error); - int blockSize = SymmetricBlockAlgorithmUtils.getBlockSize(symmetricBlockAlgorithm, this.error); - if (this.HasError()) - { - - return false; - } - if (blockSize != 64 && blockSize != 128) - { - - return false; - } - - return true; - } - } + + return retValue; + + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Hmac.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Hmac.cs index a3a332ff3..f003c3290 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Hmac.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Mac/Hmac.cs @@ -1,99 +1,114 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; using System.Security; using SecurityAPICommons.Commons; using GeneXusCryptography.Commons; using SecurityAPICommons.Config; using Org.BouncyCastle.Utilities.Encoders; -using System.Security.Cryptography; using GeneXusCryptography.Hash; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Macs; using GeneXusCryptography.HashUtils; using SecurityAPICommons.Utils; +using System.IO; namespace GeneXusCryptography.Mac { - [SecuritySafeCritical] - public class Hmac : SecurityAPIObject, IHmacObject - { + [SecuritySafeCritical] + public class Hmac : SecurityAPIObject, IHmacObject + { - public Hmac() : base() - { + public Hmac() : base() + { - } + } - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - [SecuritySafeCritical] - public string calculate(string plainText, string password, string algorithm) - { - byte[] pass = SecurityUtils.GetHexa(password, "HS002", this.error); - if (this.HasError()) + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + [SecuritySafeCritical] + public string calculate(string plainText, string password, string algorithm) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("plainText", plainText, this.error); + SecurityUtils.validateStringInput("password", password, this.error); + SecurityUtils.validateStringInput("algorithm", algorithm, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + byte[] pass = SecurityUtils.HexaToByte(password, this.error); + HashUtils.HashAlgorithm hashAlgorithm = HashAlgorithmUtils.getHashAlgorithm(algorithm, this.error); + Stream input = SecurityUtils.StringToStream(plainText, this.error); + if (this.HasError()) { return ""; } + EncodingUtil eu = new EncodingUtil(); + byte[] inputText = eu.getBytes(plainText); + if (eu.HasError()) { - return ""; + error = eu.GetError(); + return null; } - - EncodingUtil eu = new EncodingUtil(); - byte[] inputBytes = eu.getBytes(plainText); - if (this.HasError()) - { - return ""; - } - Hashing hash = new Hashing(); - HashUtils.HashAlgorithm alg = HashAlgorithmUtils.getHashAlgorithm(algorithm, this.error); - if (this.HasError()) - { - return ""; - } - IDigest digest = hash.createHash(alg); - HMac engine = new HMac(digest); - try - { - engine.Init(new KeyParameter(pass)); - }catch(Exception e) + byte[] resBytes = null; + + using (Stream inputStream = new MemoryStream(inputText)) { - this.error.setError("HS003", e.Message); - return ""; + resBytes = calculate(inputStream, pass, hashAlgorithm); } - byte[] resBytes = new byte[engine.GetMacSize()]; - engine.BlockUpdate(inputBytes, 0, inputBytes.Length); - engine.DoFinal(resBytes, 0); - string result = toHexastring(resBytes); - if (!this.error.existsError()) - { - return result; - } - return ""; + return this.HasError() ? "" : Hex.ToHexString(resBytes); + } - } + [SecuritySafeCritical] + public bool verify(string plainText, string password, string mac, string algorithm) + { + this.error.cleanError(); - [SecuritySafeCritical] - public bool verify(string plainText, string password, string mac, string algorithm) - { - string res = calculate(plainText, password, algorithm); - return SecurityUtils.compareStrings(res, mac); - } - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("plainText", plainText, this.error); + SecurityUtils.validateStringInput("password", password, this.error); + SecurityUtils.validateStringInput("algorithm", algorithm, this.error); + SecurityUtils.validateStringInput("mac", mac, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ - /// - /// Gets the hexadecimal encoded representation of the digest input - /// - /// byte array - /// string Hexa respresentation of the byte array digest - private string toHexastring(byte[] digest) - { - string result = BitConverter.ToString(digest).Replace("-", string.Empty); - if (result == null || result.Length == 0) - { - this.error.setError("HS001", "Error encoding hexa"); - return ""; - } - return result; - } - } + string res = calculate(plainText, password, algorithm); + return SecurityUtils.compareStrings(res, mac); + } + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + private byte[] calculate(Stream input, byte[] password, HashUtils.HashAlgorithm algorithm) + { + + IDigest digest = new Hashing().createHash(algorithm); + if (this.HasError()) { return null; } + + HMac engine = new HMac(digest); + try + { + engine.Init(new KeyParameter(password)); + } + catch (Exception e) + { + this.error.setError("HM001", e.Message); + return null; + } + + byte[] buffer = new byte[8192]; + int n; + byte[] retValue = new byte[engine.GetMacSize()]; + try + { + while ((n = input.Read(buffer, 0, buffer.Length)) > 0) + { + engine.BlockUpdate(buffer, 0, n); + } + engine.DoFinal(retValue, 0); + } + catch (Exception e) + { + this.error.setError("HM002", e.Message); + return null; + } + return retValue; + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivation.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivation.cs index f54235843..59ceced72 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivation.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivation.cs @@ -1,4 +1,4 @@ - + using GeneXusCryptography.Commons; using SecurityAPICommons.Commons; using SecurityAPICommons.Config; @@ -6,204 +6,141 @@ using Org.BouncyCastle.Utilities.Encoders; using System; using System.Security; +using SecurityAPICommons.Utils; namespace GeneXusCryptography.PasswordDerivation { - /// - /// Implements password derivation functions - /// - [SecuritySafeCritical] - public class PasswordDerivation : SecurityAPIObject, IPasswordDerivationObject - { - - - /// - /// PasswordDerivation class constructor - /// - public PasswordDerivation() : base() - { - - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - - - - /// - /// Hashing and salting of a password with scrypt algorithm - /// - /// string to hash - /// string to use as salt - /// CPUCost must be larger than 1, a power of 2 and less than 2^(128 *blockSize / 8) - /// The blockSize must be >= 1 - /// Parallelization must be a positive integer less than or equal to Integer.MAX_VALUE / (128 * blockSize* 8) - /// fixed key length - /// Base64 hashed result - [SecuritySafeCritical] - public string DoGenerateSCrypt(string password, string salt, int CPUCost, int blockSize, int parallelization, - int keyLenght) - { - this.error.cleanError(); - if (!areSCRyptValidParameters(CPUCost, blockSize, parallelization)) - { - return ""; - } - EncodingUtil eu = new EncodingUtil(); - - byte[] encryptedBytes = SCrypt.Generate(eu.getBytes(password), Hex.Decode(salt), CPUCost, blockSize, parallelization, keyLenght); - string result = Base64.ToBase64String(encryptedBytes); - if (result == null || result.Length == 0) - { - this.error.setError("PD009", "SCrypt generation error"); - return ""; - } - this.error.cleanError(); - return result; - } - - /// - /// Calculates SCrypt digest with arbitrary fixed parameters: CPUCost (N) = 16384, blockSize(r) = 8, parallelization(p) = 1, keyLenght = 256 - /// - /// string to hash - /// string to use as salt - /// Base64 string generated result - [SecuritySafeCritical] - public string DoGenerateDefaultSCrypt(string password, string salt) - { - int N = 16384; - int r = 8; - int p = 1; - int keyLenght = 256; - return DoGenerateSCrypt(password, salt, N, r, p, keyLenght); - } - - /// - /// Hashing and salting of a password with bcrypt algorithm - /// - /// string to hash. the password bytes (up to 72 bytes) to use for this invocation. - /// string hexadecimal to salt. The salt lenght must be 128 bits - /// The cost of the bcrypt function grows as 2^cost. Legal values are 4..31 inclusive. - /// string Base64 hashed password to store - [SecuritySafeCritical] - public string DoGenerateBcrypt(string password, string salt, int cost) - { - this.error.cleanError(); - if (!areBCryptValidParameters(password, salt, cost)) - { - return ""; - } - EncodingUtil eu = new EncodingUtil(); - byte[] encryptedBytes = BCrypt.Generate(eu.getBytes(password), Hex.Decode(salt), cost); - string result = Base64.ToBase64String(encryptedBytes); - if (result == null || result.Length == 0) - { - this.error.setError("PD010", "Brypt generation error"); - return ""; - } - this.error.cleanError(); - return result; - } - - /// - /// Calculates Bcrypt digest with arbitrary fixed cost parameter: cost = 6 - /// - /// string to hash. the password bytes (up to 72 bytes) to use for this invocation. - /// string to salt. The salt lenght must be 128 bits - /// string Base64 hashed password to store - [SecuritySafeCritical] - public string DoGenerateDefaultBcrypt(string password, string salt) - { - int cost = 6; - return DoGenerateBcrypt(password, salt, cost); - } - - [SecuritySafeCritical] - public string doGenerateArgon2(string argon2Version10, string argon2HashType, int iterations, int memory, - int parallelism, string password, string salt, int hashLength) - { - this.error.setError("PD011", "Not implemented function for Net"); - return ""; - } - - [SecuritySafeCritical] - public string DoGenerateArgon2(string argon2Version10, string argon2HashType, int iterations, int memory, - int parallelism, String password, string salt, int hashLength) - { - this.error.setError("PD012", "Not implemented yet"); - return ""; - } - - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - - - /// - /// Get BCrypt algorithm parameters revised - /// - /// password string to hash. the password bytes (up to 72 bytes) to use for this invocation. - /// salt string to salt. The salt lenght must be 128 bits - /// cost The cost of the bcrypt function grows as 2^cost. Legal values are 4..31 inclusive. - /// true if BCrypt parameters are correct - private bool areBCryptValidParameters(string pwd, string salt, int cost) - { - EncodingUtil eu = new EncodingUtil(); - byte[] pwdBytes = eu.getBytes(pwd); - byte[] saltBytes = Hex.Decode(salt); - if (saltBytes.Length * 8 != 128) - { - this.error.setError("PD008", "The salt lenght must be 128 bits"); - return false; - } - if (cost < 4 || cost > 31) - { - this.error.setError("PD007", "The cost of the bcrypt function grows as 2^cost. Legal values are 4..31 inclusive."); - return false; - } - if (pwdBytes.Length > 72) - { - this.error.setError("PD006", "The password bytes (up to 72 bytes) to use for this invocation."); - return false; - } - return true; - } - - /// - /// Get Scrypt algorithm parameters revised - /// - /// CPUCost must be larger than 1, a power of 2 and less than 2^(128 * blockSize / 8) - /// The blockSize must be >= 1 - /// Parallelization must be a positive integer less than or equal to Integer.MAX_VALUE / (128 * blockSize* 8) - /// true if SCrypt parameters are correct - private bool areSCRyptValidParameters(int CPUCost, int blockSize, int parallelization) - { - if (blockSize < 1) - { - this.error.setError("PD005", "The blockSize must be >= 1"); - return false; - } - if (CPUCost < 2 || CPUCost >= Math.Pow(2, 128 * blockSize / 8) || !isPowerOfTwo(CPUCost)) - { - this.error.setError("PD004", "CPUCost must be larger than 1, a power of 2 and less than 2^(128 * blockSize / 8)"); - return false; - } - if (parallelization <= 0 || parallelization > int.MaxValue / (128 * blockSize * 8)) - { - this.error.setError("PD003", "Parallelization must be a positive integer less than or equal to Integer.MAX_VALUE / (128 * blockSize * 8)"); - return false; - } - return true; - } - - /// - /// - /// - /// int number to test - /// true if number is power of 2 - private static bool isPowerOfTwo(int number) - { - return number > 0 && ((number & (number - 1)) == 0); - } - - } + /// + /// Implements password derivation functions + /// + [SecuritySafeCritical] + public class PasswordDerivation : SecurityAPIObject, IPasswordDerivationObject + { + + + /// + /// PasswordDerivation class constructor + /// + public PasswordDerivation() : base() + { + + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + + + /// + /// Hashing and salting of a password with scrypt algorithm + /// + /// string to hash + /// string to use as salt + /// CPUCost must be larger than 1, a power of 2 and less than 2^(128 *blockSize / 8) + /// The blockSize must be >= 1 + /// Parallelization must be a positive integer less than or equal to Integer.MAX_VALUE / (128 * blockSize* 8) + /// fixed key length + /// Base64 hashed result + [SecuritySafeCritical] + public string DoGenerateSCrypt(string password, string salt, int CPUCost, int blockSize, int parallelization, + int keyLenght) + { + this.error.cleanError(); + + EncodingUtil eu = new EncodingUtil(); + byte[] bytePassword = eu.getBytes(password); + if (eu.HasError()) { this.error = eu.GetError(); } + + byte[] byteSalt = SecurityUtils.HexaToByte(salt, this.error); + if (this.HasError()) { return ""; } + + byte[] encryptedBytes = null; + try + { + encryptedBytes = SCrypt.Generate(bytePassword, byteSalt, CPUCost, blockSize, + parallelization, keyLenght); + } + catch (Exception e) + { + this.error.setError("PD001", e.Message); + return ""; + } + return Base64.ToBase64String(encryptedBytes); + } + + /// + /// Calculates SCrypt digest with arbitrary fixed parameters: CPUCost (N) = 16384, blockSize(r) = 8, parallelization(p) = 1, keyLenght = 256 + /// + /// string to hash + /// string to use as salt + /// Base64 string generated result + [SecuritySafeCritical] + public string DoGenerateDefaultSCrypt(string password, string salt) + { + int N = 16384; + int r = 8; + int p = 1; + int keyLenght = 256; + return DoGenerateSCrypt(password, salt, N, r, p, keyLenght); + } + + /// + /// Hashing and salting of a password with bcrypt algorithm + /// + /// string to hash. the password bytes (up to 72 bytes) to use for this invocation. + /// string hexadecimal to salt. The salt lenght must be 128 bits + /// The cost of the bcrypt function grows as 2^cost. Legal values are 4..31 inclusive. + /// string Base64 hashed password to store + [SecuritySafeCritical] + public string DoGenerateBcrypt(string password, string salt, int cost) + { + this.error.cleanError(); + + EncodingUtil eu = new EncodingUtil(); + byte[] bytePassword = eu.getBytes(password); + if (eu.HasError()) { this.error = eu.GetError(); } + + byte[] byteSalt = SecurityUtils.HexaToByte(salt, this.error); + if (this.HasError()) { return ""; } + + byte[] encryptedBytes = null; + + try + { + encryptedBytes = BCrypt.Generate(bytePassword, byteSalt, cost); + } + catch (Exception e) + { + this.error.setError("PD002", e.Message); + return ""; + } + + return Base64.ToBase64String(encryptedBytes); + } + + /// + /// Calculates Bcrypt digest with arbitrary fixed cost parameter: cost = 6 + /// + /// string to hash. the password bytes (up to 72 bytes) to use for this invocation. + /// string to salt. The salt lenght must be 128 bits + /// string Base64 hashed password to store + [SecuritySafeCritical] + public string DoGenerateDefaultBcrypt(string password, string salt) + { + int cost = 6; + return DoGenerateBcrypt(password, salt, cost); + } + + [SecuritySafeCritical] + public string DoGenerateArgon2(string argon2Version10, string argon2HashType, int iterations, int memory, + int parallelism, String password, string salt, int hashLength) + { + this.error.setError("PD004", "Not implemented function for Net"); + return ""; + + } + + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivationAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivationAlgorithm.cs index 9f43956d0..97aa812fe 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivationAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/PasswordDerivation/PasswordDerivationAlgorithm.cs @@ -8,81 +8,81 @@ namespace GeneXusCryptography.PasswordDerivation { - /// - /// Implements PasswordDerivationAlgorithm enumerated - /// - [SecuritySafeCritical] - public enum PasswordDerivationAlgorithm - { + /// + /// Implements PasswordDerivationAlgorithm enumerated + /// + [SecuritySafeCritical] + public enum PasswordDerivationAlgorithm + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - NONE, SCrypt, Bcrypt, Argon2 + NONE, SCrypt, Bcrypt, Argon2 #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - } - /// - /// Implements PasswordDerivationAlgorithm associated functions - /// - [SecuritySafeCritical] - public static class PasswordDerivationAlgorithmUtils - { - /// - /// Mapping between string name and PasswordDerivationAlgorithm enum representation - /// - /// string passwordDerivationAlgorithm - /// Error type for error management - /// PasswordDerivationAlgorithm enum representation - public static PasswordDerivationAlgorithm getPasswordDerivationAlgorithm(string passwordDerivationAlgorithm, Error error) - { + } + /// + /// Implements PasswordDerivationAlgorithm associated functions + /// + [SecuritySafeCritical] + public static class PasswordDerivationAlgorithmUtils + { + /// + /// Mapping between string name and PasswordDerivationAlgorithm enum representation + /// + /// string passwordDerivationAlgorithm + /// Error type for error management + /// PasswordDerivationAlgorithm enum representation + public static PasswordDerivationAlgorithm getPasswordDerivationAlgorithm(string passwordDerivationAlgorithm, Error error) + { if (error == null) return PasswordDerivationAlgorithm.NONE; - if(passwordDerivationAlgorithm == null) + if (passwordDerivationAlgorithm == null) { - error.setError("PD001", "Unrecognized PasswordDerivationAlgorithm"); + error.setError("PDA03", "Unrecognized PasswordDerivationAlgorithm"); return PasswordDerivationAlgorithm.NONE; } switch (passwordDerivationAlgorithm.Trim()) - { - case "SCrypt": - return PasswordDerivationAlgorithm.SCrypt; - case "Bcrypt": - return PasswordDerivationAlgorithm.Bcrypt; - case "Argon2": - return PasswordDerivationAlgorithm.Argon2; - default: - error.setError("PD001", "Unrecognized PasswordDerivationAlgorithm"); - return PasswordDerivationAlgorithm.NONE; - } - } - /// - /// Mapping between and PasswordDerivationAlgorithm enum representation and string name - /// - /// PasswordDerivationAlgorithm enum, algorithm name - /// Error type for error management - /// PasswordDerivationAlgorithm value in string - public static string valueOf(PasswordDerivationAlgorithm passwordDerivationAlgorithm, Error error) - { - if(error == null) return "Unrecognized algorithm"; + { + case "SCrypt": + return PasswordDerivationAlgorithm.SCrypt; + case "Bcrypt": + return PasswordDerivationAlgorithm.Bcrypt; + case "Argon2": + return PasswordDerivationAlgorithm.Argon2; + default: + error.setError("PDA01", "Unrecognized PasswordDerivationAlgorithm"); + return PasswordDerivationAlgorithm.NONE; + } + } + /// + /// Mapping between and PasswordDerivationAlgorithm enum representation and string name + /// + /// PasswordDerivationAlgorithm enum, algorithm name + /// Error type for error management + /// PasswordDerivationAlgorithm value in string + public static string valueOf(PasswordDerivationAlgorithm passwordDerivationAlgorithm, Error error) + { + if (error == null) return "Unrecognized algorithm"; switch (passwordDerivationAlgorithm) - { - case PasswordDerivationAlgorithm.SCrypt: - return "SCrypt"; - case PasswordDerivationAlgorithm.Bcrypt: - return "Bcrypt"; - case PasswordDerivationAlgorithm.Argon2: - return "Argon2"; - default: - error.setError("PD002", "Unrecognized PasswordDerivationAlgorithm"); - return "Unrecognized algorithm"; - } - } + { + case PasswordDerivationAlgorithm.SCrypt: + return "SCrypt"; + case PasswordDerivationAlgorithm.Bcrypt: + return "Bcrypt"; + case PasswordDerivationAlgorithm.Argon2: + return "Argon2"; + default: + error.setError("PDA02", "Unrecognized PasswordDerivationAlgorithm"); + return "Unrecognized algorithm"; + } + } - /// - /// Manage Enumerable enum - /// - /// PasswordDerivationAlgorithm enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(PasswordDerivationAlgorithm)).Cast(); - } + /// + /// Manage Enumerable enum + /// + /// PasswordDerivationAlgorithm enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(PasswordDerivationAlgorithm)).Cast(); + } - } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricBlockCipher.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricBlockCipher.cs index 911e2926c..d242273ff 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricBlockCipher.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricBlockCipher.cs @@ -12,615 +12,736 @@ using GeneXusCryptography.SymmetricUtils; using SecurityAPICommons.Config; using SecurityAPICommons.Utils; +using System.IO; namespace GeneXusCryptography.Symmetric { - /// - /// Implements Symmetric block cipher engines and the methos to encrypt and decrypt strings - /// - [SecuritySafeCritical] - public class SymmetricBlockCipher : SecurityAPIObject, ISymmetricBlockCipherObject - { - - - - - /// - /// SymmetricBlockCipher class constructor - /// - public SymmetricBlockCipher() : base() - { - - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - - - - /// - /// Encrypts the given text with an AEAD encryption algorithm - /// - /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name - /// string SymmetricBlockModes enum, symmetric block mode name - /// string Hexa key for the algorithm excecution - /// int macSize in bits for MAC length for AEAD Encryption algorithm - /// string Hexa nonce for MAC length for AEAD Encryption algorithm - /// string UTF-8 plain text to encrypt - /// - public string DoAEADEncrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, - string key, int macSize, string nonce, string plainText) - { - this.error.cleanError(); - SymmetricBlockAlgorithm algorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(symmetricBlockAlgorithm, this.error); - SymmetricBlockMode mode = SymmetricBlockModeUtils.getSymmetricBlockMode(symmetricBlockMode, this.error); - if (this.error.existsError()) - { - return ""; - } - - IBlockCipher engine = getCipherEngine(algorithm); - IAeadBlockCipher bbc = getAEADCipherMode(engine, mode); - if (this.error.existsError() && !(string.Compare(this.error.SecApiCode, "SB016", true, System.Globalization.CultureInfo.InvariantCulture) == 0)) - { - return ""; - } - byte[] nonceBytes = SecurityUtils.GetHexa(nonce, "SB024", this.error); - byte[] keyBytes = SecurityUtils.GetHexa(key, "SB024", this.error); - if(this.HasError()) + /// + /// Implements Symmetric block cipher engines and the methos to encrypt and decrypt strings + /// + [SecuritySafeCritical] + public class SymmetricBlockCipher : SecurityAPIObject, ISymmetricBlockCipherObject + { + + + + + /// + /// SymmetricBlockCipher class constructor + /// + public SymmetricBlockCipher() : base() + { + + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + + + /// + /// Encrypts the given text with an AEAD encryption algorithm + /// + /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name + /// string SymmetricBlockModes enum, symmetric block mode name + /// string Hexa key for the algorithm excecution + /// int macSize in bits for MAC length for AEAD Encryption algorithm + /// string Hexa nonce for MAC length for AEAD Encryption algorithm + /// string UTF-8 plain text to encrypt + /// + public string DoAEADEncrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, + string key, int macSize, string nonce, string plainText) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("nonce", nonce, this.error); + SecurityUtils.validateStringInput("plainText", plainText, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + EncodingUtil eu = new EncodingUtil(); + byte[] txtBytes = eu.getBytes(plainText); + if (eu.HasError()) { this.error = eu.GetError(); } + if (this.HasError()) { return ""; } + + byte[] encryptedBytes = SetUp(symmetricBlockAlgorithm, symmetricBlockMode, null, nonce, key, txtBytes, macSize, true, true, false, null, null); + if (this.HasError()) { return ""; } + + return Base64.ToBase64String(encryptedBytes); + + } + /// + /// Decrypts the given encrypted text with an AEAD encryption algorithm + /// + /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name + /// string SymmetricBlockModes enum, symmetric block mode name + /// string Hexa key for the algorithm excecution + /// int macSize in bits for MAC length for AEAD Encryption algorithm + /// string Hexa nonce for MAC length for AEAD Encryption algorithm + /// string Base64 text to decrypt + /// + public string DoAEADDecrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, + string key, int macSize, string nonce, string encryptedInput) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("nonce", nonce, this.error); + SecurityUtils.validateStringInput("encryptedInput", encryptedInput, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + byte[] input = null; + try + { + input = Base64.Decode(encryptedInput); + } + catch (Exception e) { + this.error.setError("SB001", e.Message); return ""; } - KeyParameter keyParam = new KeyParameter(keyBytes); - - AeadParameters AEADparams = new AeadParameters(keyParam, macSize, nonceBytes); - try - { - bbc.Init(true, AEADparams); - }catch(Exception e) + byte[] decryptedBytes = SetUp(symmetricBlockAlgorithm, symmetricBlockMode, null, nonce, key, input, macSize, false, true, false, null, null); + if (this.HasError()) { return ""; } + + EncodingUtil eu = new EncodingUtil(); + String result = eu.getString(decryptedBytes); + if (eu.HasError()) { - this.error.setError("SB029", e.Message); + this.error = eu.GetError(); return ""; } - EncodingUtil eu = new EncodingUtil(); - byte[] inputBytes = eu.getBytes(plainText); - if (eu.GetError().existsError()) - { - this.error = eu.GetError(); - return ""; - } - byte[] outputBytes = new byte[bbc.GetOutputSize(inputBytes.Length)]; - int length = bbc.ProcessBytes(inputBytes, 0, inputBytes.Length, outputBytes, 0); - try - { - bbc.DoFinal(outputBytes, length); - } - catch (Exception) - { - this.error.setError("SB010", "AEAD encryption exception"); - return ""; - - } - string result = Base64.ToBase64String(outputBytes); - if (result == null || result.Length == 0) - { - this.error.setError("SB011", "Error encoding base64"); - return ""; - } - this.error.cleanError(); - return result; - } - /// - /// Decrypts the given encrypted text with an AEAD encryption algorithm - /// - /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name - /// string SymmetricBlockModes enum, symmetric block mode name - /// string Hexa key for the algorithm excecution - /// int macSize in bits for MAC length for AEAD Encryption algorithm - /// string Hexa nonce for MAC length for AEAD Encryption algorithm - /// string Base64 text to decrypt - /// - public string DoAEADDecrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, - string key, int macSize, string nonce, string encryptedInput) - { - this.error.cleanError(); - SymmetricBlockAlgorithm algorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(symmetricBlockAlgorithm, this.error); - SymmetricBlockMode mode = SymmetricBlockModeUtils.getSymmetricBlockMode(symmetricBlockMode, this.error); - if (this.error.existsError()) - { - return ""; - } - - IBlockCipher engine = getCipherEngine(algorithm); - IAeadBlockCipher bbc = getAEADCipherMode(engine, mode); - if (this.error.existsError() && !(string.Compare(this.error.SecApiCode, "SB016", true, System.Globalization.CultureInfo.InvariantCulture) == 0)) - { - return ""; - } - byte[] nonceBytes = SecurityUtils.GetHexa(nonce, "SB025", this.error); - byte[] keyBytes = SecurityUtils.GetHexa(key, "SB025", this.error); - if(this.HasError()) + return result.Trim(); + + } + /// + /// Encrypts the given text with a block encryption algorithm + /// + /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name + /// string SymmetricBlockModes enum, symmetric block mode name + /// string SymmetricBlockPadding enum, symmetric block padding name + /// string Hexa key for the algorithm excecution + /// string IV for the algorithm execution, must be the same length as the blockSize + /// string UTF-8 plain text to encrypt + /// string base64 encrypted text + [SecuritySafeCritical] + public string DoEncrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, + string symmetricBlockPadding, string key, string IV, string plainText) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("symmetricBlockPadding", symmetricBlockPadding, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("IV", IV, this.error); + SecurityUtils.validateStringInput("plainText", plainText, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + EncodingUtil eu = new EncodingUtil(); + byte[] inputBytes = eu.getBytes(plainText); + if (eu.HasError()) { + this.error = eu.GetError(); return ""; } - KeyParameter keyParam = new KeyParameter(keyBytes); - - AeadParameters AEADparams = new AeadParameters(keyParam, macSize, nonceBytes); + + byte[] encryptedBytes = SetUp(symmetricBlockAlgorithm, symmetricBlockMode, symmetricBlockPadding, IV, key, inputBytes, 0, true, false, false, null, null); + if (this.HasError()) { return ""; } + + return Base64.ToBase64String(encryptedBytes); + } + /// + /// Decrypts the given encrypted text with a block encryption algorithm + /// + /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name + /// string SymmetricBlockModes enum, symmetric block mode name + /// string SymmetricBlockPadding enum, symmetric block padding name + /// string Hexa key for the algorithm excecution + /// string IV for the algorithm execution, must be the same length as the blockSize + /// string Base64 text to decrypt + /// sting plaintext UTF-8 + [SecuritySafeCritical] + public string DoDecrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, + string symmetricBlockPadding, string key, string IV, string encryptedInput) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("symmetricBlockPadding", symmetricBlockPadding, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("IV", IV, this.error); + SecurityUtils.validateStringInput("encryptedInput", encryptedInput, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + byte[] input = null; try { - bbc.Init(false, AEADparams); - }catch(Exception e) + input = Base64.Decode(encryptedInput); + } + catch (Exception e) { - this.error.setError("SB030", e.Message); + this.error.setError("SB002", e.Message); return ""; } - byte[] out2 = Base64.Decode(encryptedInput); - byte[] comparisonBytes = new byte[bbc.GetOutputSize(out2.Length)]; - int length = bbc.ProcessBytes(out2, 0, out2.Length, comparisonBytes, 0); - try - { - bbc.DoFinal(comparisonBytes, length); - } - catch (Exception) - { - this.error.setError("SB012", "AEAD decryption exception"); - return ""; - } - this.error.cleanError(); - // return System.Text.Encoding.UTF8.GetString(comparisonBytes).Trim(); - EncodingUtil eu = new EncodingUtil(); - this.error = eu.GetError(); - - return eu.getString(comparisonBytes); - - } - /// - /// Encrypts the given text with a block encryption algorithm - /// - /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name - /// string SymmetricBlockModes enum, symmetric block mode name - /// string SymmetricBlockPadding enum, symmetric block padding name - /// string Hexa key for the algorithm excecution - /// string IV for the algorithm execution, must be the same length as the blockSize - /// string UTF-8 plain text to encrypt - /// string base64 encrypted text - [SecuritySafeCritical] - public string DoEncrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, - string symmetricBlockPadding, string key, string IV, string plainText) - { - this.error.cleanError(); - SymmetricBlockAlgorithm algorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(symmetricBlockAlgorithm, this.error); - SymmetricBlockMode mode = SymmetricBlockModeUtils.getSymmetricBlockMode(symmetricBlockMode, this.error); - SymmetricBlockPadding padding = SymmetricBlockPaddingUtils.getSymmetricBlockPadding(symmetricBlockPadding, this.error); - if (this.error.existsError()) - { - return ""; - } - - BufferedBlockCipher bbc = getCipher(algorithm, mode, padding); - if (this.error.existsError() && !(string.Compare(this.error.SecApiCode, "SB016", true, System.Globalization.CultureInfo.InvariantCulture) == 0)) - { - return ""; - } - byte[] byteIV = SecurityUtils.GetHexa(IV, "SB022", this.error); - byte[] byteKey = SecurityUtils.GetHexa(key, "SB022", this.error); - if (this.HasError()) + + byte[] decryptedBytes = SetUp(symmetricBlockAlgorithm, symmetricBlockMode, symmetricBlockPadding, IV, key, input, 0, false, false, false, null, null); + if (this.HasError()) { return ""; } + + EncodingUtil eu = new EncodingUtil(); + String result = eu.getString(decryptedBytes); + if (eu.HasError()) { + this.error = eu.GetError(); return ""; } - KeyParameter keyParam = new KeyParameter(byteKey); - - if (SymmetricBlockMode.ECB != mode && SymmetricBlockMode.OPENPGPCFB != mode) - { - ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, byteIV); - try{ - bbc.Init(true, keyParamWithIV); - }catch(Exception e) + return result.Trim(); + } + + [SecuritySafeCritical] + public bool DoAEADEncryptFile(String symmetricBlockAlgorithm, String symmetricBlockMode, String key, int macSize, + String nonce, String pathInputFile, String pathOutputFile) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("nonce", nonce, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + + return SetUpFile(symmetricBlockAlgorithm, symmetricBlockMode, null, nonce, key, pathInputFile, pathOutputFile, macSize, true, true); + } + + [SecuritySafeCritical] + public bool DoAEADDecryptFile(String symmetricBlockAlgorithm, String symmetricBlockMode, String key, int macSize, + String nonce, String pathInputFile, String pathOutputFile) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("nonce", nonce, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + + return SetUpFile(symmetricBlockAlgorithm, symmetricBlockMode, null, nonce, key, pathInputFile, pathOutputFile, macSize, false, true); + } + + [SecuritySafeCritical] + public bool DoEncryptFile(String symmetricBlockAlgorithm, String symmetricBlockMode, String symmetricBlockPadding, + String key, String IV, String pathInputFile, String pathOutputFile) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("symmetricBlockPadding", symmetricBlockPadding, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("IV", IV, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + + return SetUpFile(symmetricBlockAlgorithm, symmetricBlockMode, symmetricBlockPadding, IV, key, pathInputFile, pathOutputFile, 0, true, false); + } + + [SecuritySafeCritical] + public bool DoDecryptFile(String symmetricBlockAlgorithm, String symmetricBlockMode, String symmetricBlockPadding, + String key, String IV, String pathInputFile, String pathOutputFile) + { + this.error.cleanError(); + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricBlockAlgorithm", symmetricBlockAlgorithm, this.error); + SecurityUtils.validateStringInput("symmetricBlockMode", symmetricBlockMode, this.error); + SecurityUtils.validateStringInput("symmetricBlockPadding", symmetricBlockPadding, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("IV", IV, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + + return SetUpFile(symmetricBlockAlgorithm, symmetricBlockMode, symmetricBlockPadding, IV, key, pathInputFile, pathOutputFile, 0, false, false); + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + + /// + /// Gets the BufferedBlockCipher loaded with Padding, Mode and Engine to Encrypt with a Symmetric Block Algorithm + /// + /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name + /// string SymmetricBlockModes enum, symmetric block mode name + /// string SymmetricBlockPadding enum, symmetric block padding name + /// BufferedBlockCipher loaded with Padding, Mode and Engine to Encrypt with a Symmetric Block Algorithm + private BufferedBlockCipher getCipher(SymmetricBlockAlgorithm algorithm, SymmetricBlockMode mode, + SymmetricBlockPadding padding) + { + IBlockCipher engine = getCipherEngine(algorithm); + IBlockCipherPadding paddingCipher = getPadding(padding); + IBlockCipher bc; + if (mode != SymmetricBlockMode.ECB) + { + bc = getCipherMode(engine, mode); + } + else + { + bc = engine; + } + // si el padding es WITHCTS el paddingCipher es null + if (usesCTS(mode, padding)) + { + return new CtsBlockCipher(bc); // no usa el paddingCipher que es el null + } + if (padding == SymmetricBlockPadding.NOPADDING) + { + return new BufferedBlockCipher(bc); + } + else + { + return new PaddedBufferedBlockCipher(bc, paddingCipher); + } + + } + /// + /// True if it uses CTS + /// + /// string SymmetricBlockModes enum, symmetric block mode name + /// string SymmetricBlockPadding enum, symmetric block padding name + /// boolean true if it uses CTS + private static bool usesCTS(SymmetricBlockMode mode, SymmetricBlockPadding padding) + { + return mode == SymmetricBlockMode.CTS || padding == SymmetricBlockPadding.WITHCTS; + } + /// + /// Build the engine + /// + /// SymmetricBlockAlgorithm enum, algorithm name + /// IBlockCipher with the algorithm Engine + internal IBlockCipher getCipherEngine(SymmetricBlockAlgorithm algorithm) + { + + IBlockCipher engine = null; + + switch (algorithm) + { + case SymmetricBlockAlgorithm.AES: + engine = new AesEngine(); + break; + case SymmetricBlockAlgorithm.BLOWFISH: + engine = new BlowfishEngine(); + break; + case SymmetricBlockAlgorithm.CAMELLIA: + engine = new CamelliaEngine(); + break; + case SymmetricBlockAlgorithm.CAST5: + engine = new Cast5Engine(); + break; + case SymmetricBlockAlgorithm.CAST6: + engine = new Cast6Engine(); + break; + case SymmetricBlockAlgorithm.DES: + engine = new DesEngine(); + break; + case SymmetricBlockAlgorithm.TRIPLEDES: + engine = new DesEdeEngine(); + break; + case SymmetricBlockAlgorithm.DSTU7624_128: + engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_128, this.error)); + break; + case SymmetricBlockAlgorithm.DSTU7624_256: + engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_256, this.error)); + break; + case SymmetricBlockAlgorithm.DSTU7624_512: + engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_512, this.error)); + break; + case SymmetricBlockAlgorithm.GOST28147: + engine = new Gost28147Engine(); + break; + case SymmetricBlockAlgorithm.NOEKEON: + engine = new NoekeonEngine(); + break; + case SymmetricBlockAlgorithm.RC2: + engine = new RC2Engine(); + break; + case SymmetricBlockAlgorithm.RC532: + engine = new RC532Engine(); + break; + case SymmetricBlockAlgorithm.RC564: + engine = new RC564Engine(); + break; + case SymmetricBlockAlgorithm.RC6: + engine = new RC6Engine(); + break; + case SymmetricBlockAlgorithm.RIJNDAEL_128: + engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_128, this.error)); + break; + case SymmetricBlockAlgorithm.RIJNDAEL_160: + engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_160, this.error)); + break; + case SymmetricBlockAlgorithm.RIJNDAEL_192: + engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_192, this.error)); + break; + case SymmetricBlockAlgorithm.RIJNDAEL_224: + engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_224, this.error)); + break; + case SymmetricBlockAlgorithm.RIJNDAEL_256: + engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_256, this.error)); + break; + case SymmetricBlockAlgorithm.SEED: + engine = new SeedEngine(); + break; + case SymmetricBlockAlgorithm.SERPENT: + engine = new SerpentEngine(); + break; + case SymmetricBlockAlgorithm.SKIPJACK: + engine = new SkipjackEngine(); + break; + case SymmetricBlockAlgorithm.SM4: + engine = new SM4Engine(); + break; + case SymmetricBlockAlgorithm.TEA: + engine = new TeaEngine(); + break; + case SymmetricBlockAlgorithm.THREEFISH_256: + engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_256, this.error)); + break; + case SymmetricBlockAlgorithm.THREEFISH_512: + engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_512, this.error)); + break; + case SymmetricBlockAlgorithm.THREEFISH_1024: + engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_1024, this.error)); + break; + case SymmetricBlockAlgorithm.TWOFISH: + engine = new TwofishEngine(); + break; + case SymmetricBlockAlgorithm.XTEA: + engine = new XteaEngine(); + break; + default: + this.error.setError("SB003", "Unrecognized symmetric block algoritm"); + break; + } + return engine; + + } + /// + /// Builds an IBlockCipherPadding + /// + /// SymmetricBlockPadding enum, padding name + /// IBlockCipherPadding with loaded padding type, if padding is WITHCTS returns null + private IBlockCipherPadding getPadding(SymmetricBlockPadding padding) + { + + IBlockCipherPadding paddingCipher = null; + + switch (padding) + { + case SymmetricBlockPadding.NOPADDING: + paddingCipher = null; + break; + case SymmetricBlockPadding.ISO7816D4PADDING: + paddingCipher = new ISO7816d4Padding(); + break; + case SymmetricBlockPadding.ISO10126D2PADDING: + paddingCipher = new ISO10126d2Padding(); + break; + case SymmetricBlockPadding.PKCS7PADDING: + paddingCipher = new Pkcs7Padding(); + break; + case SymmetricBlockPadding.WITHCTS: + break; + case SymmetricBlockPadding.X923PADDING: + paddingCipher = new X923Padding(); + break; + case SymmetricBlockPadding.ZEROBYTEPADDING: + paddingCipher = new ZeroBytePadding(); + break; + default: + this.error.setError("SB004", "Unrecognized symmetric block padding."); + break; + } + return paddingCipher; + } + /// + /// Buils an AEADBlockCipher engine + /// + /// BlockCipher engine + /// SymmetricBlockModes enum, symmetric block mode name + /// AEADBlockCipher loaded with a given BlockCipher + private IAeadBlockCipher getAEADCipherMode(IBlockCipher blockCipher, SymmetricBlockMode mode) + { + + IAeadBlockCipher bc = null; + + switch (mode) + { + case SymmetricBlockMode.AEAD_CCM: + bc = new CcmBlockCipher(blockCipher); + break; + case SymmetricBlockMode.AEAD_EAX: + bc = new EaxBlockCipher(blockCipher); + break; + case SymmetricBlockMode.AEAD_GCM: + bc = new GcmBlockCipher(blockCipher); + break; + case SymmetricBlockMode.AEAD_KCCM: + bc = new KCcmBlockCipher(blockCipher); + break; + default: + this.error.setError("SB005", "Unrecognized symmetric AEAD mode"); + break; + } + return bc; + + } + /// + /// Buisl a BlockCipher with a mode + /// + /// BlockCipher loaded with the algorithm Engine + /// SymmetricBlockModes enum, mode name + /// BlockCipher with mode loaded + private IBlockCipher getCipherMode(IBlockCipher blockCipher, SymmetricBlockMode mode) + { + + IBlockCipher bc = null; + + switch (mode) + { + case SymmetricBlockMode.ECB: + case SymmetricBlockMode.NONE: + bc = blockCipher; + break; + case SymmetricBlockMode.CBC: + bc = new CbcBlockCipher(blockCipher); + break; + case SymmetricBlockMode.CFB: + bc = new CfbBlockCipher(blockCipher, blockCipher.GetBlockSize()); + break; + case SymmetricBlockMode.CTR: + bc = new SicBlockCipher(blockCipher); + break; + case SymmetricBlockMode.CTS: + bc = new CbcBlockCipher(blockCipher); + break; + case SymmetricBlockMode.GOFB: + bc = new GOfbBlockCipher(blockCipher); + break; + case SymmetricBlockMode.OFB: + bc = new OfbBlockCipher(blockCipher, blockCipher.GetBlockSize()); + break; + case SymmetricBlockMode.OPENPGPCFB: + bc = new OpenPgpCfbBlockCipher(blockCipher); + break; + case SymmetricBlockMode.SIC: + blockCipher = new SicBlockCipher(blockCipher); + break; + + default: + this.error.setError("SB006", "Unrecognized symmetric block mode"); + break; + } + return bc; + } + + private byte[] SetUp(string symmetricBlockAlgorithm, string symmetricBlockMode, string symmetricBlockPadding, string nonce, string key, byte[] input, int macSize, bool toEncrypt, bool isAEAD, bool isFile, string pathInput, string pathOutput) + { + SymmetricBlockAlgorithm algorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(symmetricBlockAlgorithm, + this.error); + SymmetricBlockMode mode = SymmetricBlockModeUtils.getSymmetricBlockMode(symmetricBlockMode, this.error); + SymmetricBlockPadding padding = SymmetricBlockPadding.NOPADDING; + if (!isAEAD) + { + padding = SymmetricBlockPaddingUtils.getSymmetricBlockPadding(symmetricBlockPadding, + this.error); + } + + byte[] nonceBytes = SecurityUtils.HexaToByte(nonce, this.error); + byte[] keyBytes = SecurityUtils.HexaToByte(key, this.error); + + if (this.HasError()) { return null; } + + return isAEAD ? encryptAEAD(algorithm, mode, keyBytes, nonceBytes, input, macSize, toEncrypt, isFile, pathInput, pathOutput) : encrypt(algorithm, mode, padding, keyBytes, nonceBytes, input, toEncrypt, isFile, pathInput, pathOutput); + + } + + + private byte[] encryptAEAD(SymmetricBlockAlgorithm algorithm, SymmetricBlockMode mode, byte[] key, byte[] nonce, byte[] txt, int macSize, bool toEncrypt, bool isFile, string pathInput, string pathOutput) + { + IBlockCipher engine = getCipherEngine(algorithm); + IAeadBlockCipher bbc = getAEADCipherMode(engine, mode); + if (this.HasError()) { return null; } + + KeyParameter keyParam = new KeyParameter(key); + AeadParameters AEADparams = new AeadParameters(keyParam, macSize, nonce); + + try + { + bbc.Init(toEncrypt, AEADparams); + } + catch (Exception e) + { + this.error.setError("SB007", e.Message); + return null; + } + byte[] outputBytes = null; + if (isFile) + { + try { - this.error.setError("SB025", e.Message); - return ""; + byte[] inBuffer = new byte[1024]; + byte[] outBuffer = new byte[bbc.GetOutputSize(1024)]; + outBuffer = new byte[bbc.GetBlockSize() + bbc.GetOutputSize(inBuffer.Length)]; + int inCount = 0; + int outCount = 0; + using (FileStream inputStream = new FileStream(pathInput, FileMode.Open, FileAccess.Read)) + { + using (FileStream outputStream = new FileStream(pathOutput, FileMode.Create, FileAccess.Write)) + { + while ((inCount = inputStream.Read(inBuffer, 0, inBuffer.Length)) > 0) + { + outCount = bbc.ProcessBytes(inBuffer, 0, inCount, outBuffer, 0); + outputStream.Write(outBuffer, 0, outCount); + } + outCount = bbc.DoFinal(outBuffer, 0); + + outputStream.Write(outBuffer, 0, outCount); + } + } } - } - else - { + catch (Exception e) + { + this.error.setError("SB011", e.Message); + return null; + } + outputBytes = new byte[1]; + } + else + { + outputBytes = new byte[bbc.GetOutputSize(txt.Length)]; try { - bbc.Init(true, keyParam); - }catch(Exception e) + + int length = bbc.ProcessBytes(txt, 0, txt.Length, outputBytes, 0); + bbc.DoFinal(outputBytes, length); + } + catch (Exception e) { - this.error.setError("SB026", e.Message); - return ""; + this.error.setError("SB008", e.Message); + return null; } - } - - EncodingUtil eu = new EncodingUtil(); - byte[] inputBytes = eu.getBytes(plainText); - if (eu.GetError().existsError()) - { - this.error = eu.GetError(); - return ""; - } - byte[] outputBytes = new byte[bbc.GetOutputSize(inputBytes.Length)]; - int length = bbc.ProcessBytes(inputBytes, 0, inputBytes.Length, outputBytes, 0); - try - { - bbc.DoFinal(outputBytes, length); - } - catch (Exception) - { - this.error.setError("SB013", "Block encryption exception"); - return ""; - } - string result = Base64.ToBase64String(outputBytes); - if (result == null || result.Length == 0) - { - this.error.setError("SB014", "Error encoding base64"); - return ""; - } - this.error.cleanError(); - return result; - } - /// - /// Decrypts the given encrypted text with a block encryption algorithm - /// - /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name - /// string SymmetricBlockModes enum, symmetric block mode name - /// string SymmetricBlockPadding enum, symmetric block padding name - /// string Hexa key for the algorithm excecution - /// string IV for the algorithm execution, must be the same length as the blockSize - /// string Base64 text to decrypt - /// sting plaintext UTF-8 - [SecuritySafeCritical] - public string DoDecrypt(string symmetricBlockAlgorithm, string symmetricBlockMode, - string symmetricBlockPadding, string key, string IV, string encryptedInput) - { - this.error.cleanError(); - SymmetricBlockAlgorithm algorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(symmetricBlockAlgorithm, this.error); - SymmetricBlockMode mode = SymmetricBlockModeUtils.getSymmetricBlockMode(symmetricBlockMode, this.error); - SymmetricBlockPadding padding = SymmetricBlockPaddingUtils.getSymmetricBlockPadding(symmetricBlockPadding, this.error); - if (this.error.existsError()) - { - return ""; - } - - BufferedBlockCipher bbc = getCipher(algorithm, mode, padding); - if (this.error.existsError() && !(string.Compare(this.error.SecApiCode, "SB016", true, System.Globalization.CultureInfo.InvariantCulture) == 0)) - { - return ""; - } - byte[] bytesKey = SecurityUtils.GetHexa(key, "SB023", this.error); - byte[] bytesIV = SecurityUtils.GetHexa(IV, "SB023", this.error); - if (this.HasError()) - { - return ""; + } + return outputBytes; + + } + - KeyParameter keyParam = new KeyParameter(bytesKey); - if (SymmetricBlockMode.ECB != mode && SymmetricBlockMode.OPENPGPCFB != mode) - { - ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, bytesIV); + + private byte[] encrypt(SymmetricBlockAlgorithm algorithm, SymmetricBlockMode mode, SymmetricBlockPadding padding, byte[] key, byte[] iv, byte[] input, bool toEncrypt, bool isFile, string pathInput, string pathOutput) + { + + BufferedBlockCipher bbc = getCipher(algorithm, mode, padding); + KeyParameter keyParam = new KeyParameter(key); + if (this.HasError()) { return null; } + + try + { + if (SymmetricBlockMode.ECB != mode && SymmetricBlockMode.OPENPGPCFB != mode) + { + ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv); + bbc.Init(toEncrypt, keyParamWithIV); + } + else + { + bbc.Init(toEncrypt, keyParam); + } + } + catch (Exception e) + { + this.error.setError("SB009", e.Message); + return null; + } + byte[] outputBytes = null; + if (isFile) + { try { - bbc.Init(false, keyParamWithIV); - }catch(Exception e) + byte[] inBuffer = new byte[1024]; + byte[] outBuffer = new byte[bbc.GetOutputSize(1024)]; + outBuffer = new byte[bbc.GetBlockSize() + bbc.GetOutputSize(inBuffer.Length)]; + int inCount = 0; + int outCount = 0; + using (FileStream inputStream = new FileStream(pathInput, FileMode.Open, FileAccess.Read)) + { + using (FileStream outputStream = new FileStream(pathOutput, FileMode.Create, FileAccess.Write)) + { + while ((inCount = inputStream.Read(inBuffer, 0, inBuffer.Length)) > 0) + { + outCount = bbc.ProcessBytes(inBuffer, 0, inCount, outBuffer, 0); + outputStream.Write(outBuffer, 0, outCount); + } + outCount = bbc.DoFinal(outBuffer, 0); + + outputStream.Write(outBuffer, 0, outCount); + } + } + } + catch (Exception e) { - this.error.setError("SB027", e.Message); - return ""; + this.error.setError("SB012", e.Message); + return null; } - } - else - { + outputBytes = new byte[1]; + + } + else + { + outputBytes = new byte[bbc.GetOutputSize(input.Length)]; try { - bbc.Init(false, keyParam); - }catch(Exception e) + + int length = bbc.ProcessBytes(input, 0, input.Length, outputBytes, 0); + int length2 = bbc.DoFinal(outputBytes, length); + + } + catch (Exception e) { - this.error.setError("SB028", e.Message); - return ""; + this.error.setError("SB010", e.Message); + return null; } - } - - byte[] out2 = Base64.Decode(encryptedInput); - byte[] comparisonBytes = new byte[bbc.GetOutputSize(out2.Length)]; - int length = bbc.ProcessBytes(out2, 0, out2.Length, comparisonBytes, 0); - try - { - bbc.DoFinal(comparisonBytes, length); - } - catch (Exception) - { - this.error.setError("SB015", "Block decryption exception"); - return ""; - } - this.error.cleanError(); - - EncodingUtil eu = new EncodingUtil(); - this.error = eu.GetError(); - return eu.getString(comparisonBytes); - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - - /// - /// Gets the BufferedBlockCipher loaded with Padding, Mode and Engine to Encrypt with a Symmetric Block Algorithm - /// - /// string SymmetricBlockAlgorithm enum, symmetric block algorithm name - /// string SymmetricBlockModes enum, symmetric block mode name - /// string SymmetricBlockPadding enum, symmetric block padding name - /// BufferedBlockCipher loaded with Padding, Mode and Engine to Encrypt with a Symmetric Block Algorithm - private BufferedBlockCipher getCipher(SymmetricBlockAlgorithm algorithm, SymmetricBlockMode mode, - SymmetricBlockPadding padding) - { - IBlockCipher engine = getCipherEngine(algorithm); - IBlockCipherPadding paddingCipher = getPadding(padding); - IBlockCipher bc; - if (mode != SymmetricBlockMode.ECB) - { - bc = getCipherMode(engine, mode); - } - else - { - bc = engine; - } - // si el padding es WITHCTS el paddingCipher es null - if (usesCTS(mode, padding)) - { - return new CtsBlockCipher(bc); // no usa el paddingCipher que es el null - } - if (padding == SymmetricBlockPadding.NOPADDING) - { - return new BufferedBlockCipher(bc); - } - else - { - return new PaddedBufferedBlockCipher(bc, paddingCipher); - } - - } - /// - /// True if it uses CTS - /// - /// string SymmetricBlockModes enum, symmetric block mode name - /// string SymmetricBlockPadding enum, symmetric block padding name - /// boolean true if it uses CTS - private static bool usesCTS(SymmetricBlockMode mode, SymmetricBlockPadding padding) - { - return mode == SymmetricBlockMode.CTS || padding == SymmetricBlockPadding.WITHCTS; - } - /// - /// Build the engine - /// - /// SymmetricBlockAlgorithm enum, algorithm name - /// IBlockCipher with the algorithm Engine - internal IBlockCipher getCipherEngine(SymmetricBlockAlgorithm algorithm) - { - - IBlockCipher engine = null; - - switch (algorithm) - { - case SymmetricBlockAlgorithm.AES: - engine = new AesEngine(); - break; - case SymmetricBlockAlgorithm.BLOWFISH: - engine = new BlowfishEngine(); - break; - case SymmetricBlockAlgorithm.CAMELLIA: - engine = new CamelliaEngine(); - break; - case SymmetricBlockAlgorithm.CAST5: - engine = new Cast5Engine(); - break; - case SymmetricBlockAlgorithm.CAST6: - engine = new Cast6Engine(); - break; - case SymmetricBlockAlgorithm.DES: - engine = new DesEngine(); - break; - case SymmetricBlockAlgorithm.TRIPLEDES: - engine = new DesEdeEngine(); - break; - case SymmetricBlockAlgorithm.DSTU7624_128: - engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_128, this.error)); - break; - case SymmetricBlockAlgorithm.DSTU7624_256: - engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_256, this.error)); - break; - case SymmetricBlockAlgorithm.DSTU7624_512: - engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_512, this.error)); - break; - case SymmetricBlockAlgorithm.GOST28147: - engine = new Gost28147Engine(); - break; - case SymmetricBlockAlgorithm.NOEKEON: - engine = new NoekeonEngine(); - break; - case SymmetricBlockAlgorithm.RC2: - engine = new RC2Engine(); - break; - case SymmetricBlockAlgorithm.RC532: - engine = new RC532Engine(); - break; - case SymmetricBlockAlgorithm.RC564: - engine = new RC564Engine(); - break; - case SymmetricBlockAlgorithm.RC6: - engine = new RC6Engine(); - break; - case SymmetricBlockAlgorithm.RIJNDAEL_128: - engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_128, this.error)); - break; - case SymmetricBlockAlgorithm.RIJNDAEL_160: - engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_160, this.error)); - break; - case SymmetricBlockAlgorithm.RIJNDAEL_192: - engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_192, this.error)); - break; - case SymmetricBlockAlgorithm.RIJNDAEL_224: - engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_224, this.error)); - break; - case SymmetricBlockAlgorithm.RIJNDAEL_256: - engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_256, this.error)); - break; - case SymmetricBlockAlgorithm.SEED: - engine = new SeedEngine(); - break; - case SymmetricBlockAlgorithm.SERPENT: - engine = new SerpentEngine(); - break; - case SymmetricBlockAlgorithm.SKIPJACK: - engine = new SkipjackEngine(); - break; - case SymmetricBlockAlgorithm.SM4: - engine = new SM4Engine(); - break; - case SymmetricBlockAlgorithm.TEA: - engine = new TeaEngine(); - break; - case SymmetricBlockAlgorithm.THREEFISH_256: - engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_256, this.error)); - break; - case SymmetricBlockAlgorithm.THREEFISH_512: - engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_512, this.error)); - break; - case SymmetricBlockAlgorithm.THREEFISH_1024: - engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_1024, this.error)); - break; - case SymmetricBlockAlgorithm.TWOFISH: - engine = new TwofishEngine(); - break; - case SymmetricBlockAlgorithm.XTEA: - engine = new XteaEngine(); - break; - default: - this.error.setError("SB020", "Cipher " + algorithm + " not recognised."); - break; - } - return engine; - - } - /// - /// Builds an IBlockCipherPadding - /// - /// SymmetricBlockPadding enum, padding name - /// IBlockCipherPadding with loaded padding type, if padding is WITHCTS returns null - private IBlockCipherPadding getPadding(SymmetricBlockPadding padding) - { - - IBlockCipherPadding paddingCipher = null; - - switch (padding) - { - case SymmetricBlockPadding.NOPADDING: - paddingCipher = null; - break; - case SymmetricBlockPadding.ISO7816D4PADDING: - paddingCipher = new ISO7816d4Padding(); - break; - case SymmetricBlockPadding.ISO10126D2PADDING: - paddingCipher = new ISO10126d2Padding(); - break; - case SymmetricBlockPadding.PKCS7PADDING: - paddingCipher = new Pkcs7Padding(); - break; - case SymmetricBlockPadding.WITHCTS: - break; - case SymmetricBlockPadding.X923PADDING: - paddingCipher = new X923Padding(); - break; - case SymmetricBlockPadding.ZEROBYTEPADDING: - paddingCipher = new ZeroBytePadding(); - break; - default: - this.error.setError("SB018", "Cipher " + padding + " not recognised."); - break; - } - return paddingCipher; - } - /// - /// Buils an AEADBlockCipher engine - /// - /// BlockCipher engine - /// SymmetricBlockModes enum, symmetric block mode name - /// AEADBlockCipher loaded with a given BlockCipher - private IAeadBlockCipher getAEADCipherMode(IBlockCipher blockCipher, SymmetricBlockMode mode) - { - - IAeadBlockCipher bc = null; - - switch (mode) - { - case SymmetricBlockMode.AEAD_CCM: - bc = new CcmBlockCipher(blockCipher); - break; - case SymmetricBlockMode.AEAD_EAX: - bc = new EaxBlockCipher(blockCipher); - break; - case SymmetricBlockMode.AEAD_GCM: - bc = new GcmBlockCipher(blockCipher); - break; - case SymmetricBlockMode.AEAD_KCCM: - bc = new KCcmBlockCipher(blockCipher); - break; - default: - this.error.setError("SB017", "AEADCipher " + mode + " not recognised."); - break; - } - return bc; - - } - /// - /// Buisl a BlockCipher with a mode - /// - /// BlockCipher loaded with the algorithm Engine - /// SymmetricBlockModes enum, mode name - /// BlockCipher with mode loaded - private IBlockCipher getCipherMode(IBlockCipher blockCipher, SymmetricBlockMode mode) - { - - IBlockCipher bc = null; - - switch (mode) - { - case SymmetricBlockMode.ECB: - case SymmetricBlockMode.NONE: - bc = blockCipher; - break; - case SymmetricBlockMode.CBC: - bc = new CbcBlockCipher(blockCipher); - break; - case SymmetricBlockMode.CFB: - bc = new CfbBlockCipher(blockCipher, blockCipher.GetBlockSize()); - break; - case SymmetricBlockMode.CTR: - bc = new SicBlockCipher(blockCipher); - break; - case SymmetricBlockMode.CTS: - bc = new CbcBlockCipher(blockCipher); - break; - case SymmetricBlockMode.GOFB: - bc = new GOfbBlockCipher(blockCipher); - break; - case SymmetricBlockMode.OFB: - bc = new OfbBlockCipher(blockCipher, blockCipher.GetBlockSize()); - break; - case SymmetricBlockMode.OPENPGPCFB: - bc = new OpenPgpCfbBlockCipher(blockCipher); - break; - case SymmetricBlockMode.SIC: - if (blockCipher.GetBlockSize() < 16) - { - this.error.setError("SB016", - "Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)"); - } - blockCipher = new SicBlockCipher(blockCipher); - break; - } - return bc; - } - - } + } + return outputBytes; + } + + + + private bool SetUpFile(string symmetricBlockAlgorithm, string symmetricBlockMode, string symmetricBlockPadding, string nonce, string key, string pathInput, string pathOutput, int macSize, bool toEncrypt, bool isAEAD) + { + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("pathInputFile", pathInput, this.error); + SecurityUtils.validateStringInput("pathOutputFile", pathOutput, this.error); + if (this.HasError()) { return false; }; + /*******INPUT VERIFICATION - END*******/ + byte[] output = SetUp(symmetricBlockAlgorithm, symmetricBlockMode, symmetricBlockPadding, nonce, key, null, macSize, toEncrypt, isAEAD, true, pathInput, pathOutput); + return output == null ? false : true; + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricStreamCipher.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricStreamCipher.cs index ecd059ccc..faabdcd93 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricStreamCipher.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/Symmetric/SymmetricStreamCipher.cs @@ -1,11 +1,10 @@ - + using GeneXusCryptography.Commons; using GeneXusCryptography.SymmetricUtils; using SecurityAPICommons.Commons; using SecurityAPICommons.Config; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Utilities.Encoders; using System; @@ -15,224 +14,206 @@ namespace GeneXusCryptography.Symmetric { - /// - /// Implements Symmetric Stream Cipher engines and the methods to encrypt and decrypt strings - /// - [SecuritySafeCritical] - public class SymmetricStreamCipher : SecurityAPIObject, ISymmectricStreamCipherObject - { - - - public SymmetricStreamCipher() : base() - { - - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - - - - /// - /// Encrypts the given text with a stream encryption algorithm - /// - /// string SymmetrcStreamAlgorithm enum, algorithm name - /// string SymmetricBlockMode enum, mode name - /// String Hexa IV (nonce) for those algorithms that uses, ignored if not - /// string UTF-8 plain text to encrypt - /// string Base64 encrypted text with the given algorithm and parameters - [SecuritySafeCritical] - public string DoEncrypt(string symmetricStreamAlgorithm, string key, string IV, - string plainText) - { - this.GetError().cleanError(); - SymmetricStreamAlgorithm algorithm = SymmetricStreamAlgorithmUtils.getSymmetricStreamAlgorithm(symmetricStreamAlgorithm, this.GetError()); - if (this.GetError().existsError()) - { - return ""; - } - - IStreamCipher engine = getCipherEngine(algorithm); - if (this.GetError().existsError()) - { - return ""; - } - /* KeyParameter keyParam = new KeyParameter(Hex.Decode(key)); - engine.Init(true, keyParam);*/ - byte[] keyBytes = SecurityUtils.GetHexa(key, "SS007", this.error); - byte[] ivBytes = SecurityUtils.GetHexa(IV, "SS007", this.error); - if (this.HasError()) + /// + /// Implements Symmetric Stream Cipher engines and the methods to encrypt and decrypt strings + /// + [SecuritySafeCritical] + public class SymmetricStreamCipher : SecurityAPIObject, ISymmectricStreamCipherObject + { + + + public SymmetricStreamCipher() : base() + { + + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + + + /// + /// Encrypts the given text with a stream encryption algorithm + /// + /// string SymmetrcStreamAlgorithm enum, algorithm name + /// string SymmetricBlockMode enum, mode name + /// String Hexa IV (nonce) for those algorithms that uses, ignored if not + /// string UTF-8 plain text to encrypt + /// string Base64 encrypted text with the given algorithm and parameters + [SecuritySafeCritical] + public string DoEncrypt(string symmetricStreamAlgorithm, string key, string IV, + string plainText) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricStreamAlgorithm", symmetricStreamAlgorithm, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("plainText", plainText, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + EncodingUtil eu = new EncodingUtil(); + byte[] input = eu.getBytes(plainText); + if (eu.HasError()) { + this.error = eu.GetError(); return ""; } - KeyParameter keyParam = new KeyParameter(keyBytes); - if (SymmetricStreamAlgorithmUtils.usesIV(algorithm, this.GetError())) - { - if (!this.GetError().existsError()) - { - ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, ivBytes); - try - { - engine.Init(false, keyParamWithIV); - }catch(Exception e) - { - this.error.setError("SS008", e.Message); - return ""; - } - } - } - else - { - try - { - engine.Init(false, keyParam); - }catch(Exception e) - { - this.error.setError("SS009", e.Message); - return ""; - } - } - EncodingUtil eu = new EncodingUtil(); - byte[] input = eu.getBytes(plainText); - if (eu.GetError().existsError()) - { - this.error = eu.GetError(); - return ""; - } - byte[] output = new byte[input.Length]; - engine.ProcessBytes(input, 0, input.Length, output, 0); - if (output == null || output.Length == 0) - { - this.GetError().setError("SS004", "Stream encryption exception"); - return ""; - } - this.GetError().cleanError(); - return Base64.ToBase64String(output); - - } - - /// - /// Decrypts the given encrypted text with a stream encryption algorithm - /// - /// string SymmetrcStreamAlgorithm enum, algorithm name - /// string SymmetricBlockMode enum, mode name - /// String Hexa IV (nonce) for those algorithms that uses, ignored if not - /// string Base64 encrypted text with the given algorithm and parameters - /// plain text UTF-8 - [SecuritySafeCritical] - public string DoDecrypt(string symmetricStreamAlgorithm, string key, string IV, - string encryptedInput) - { - this.GetError().cleanError(); - SymmetricStreamAlgorithm algorithm = SymmetricStreamAlgorithmUtils.getSymmetricStreamAlgorithm(symmetricStreamAlgorithm, this.GetError()); - if (this.GetError().existsError()) - { - return ""; - } - - IStreamCipher engine = getCipherEngine(algorithm); - if (this.GetError().existsError()) - { - return ""; - } - - /* KeyParameter keyParam = new KeyParameter(Hex.Decode(key)); - engine.Init(false, keyParam);*/ - byte[] keyBytes = SecurityUtils.GetHexa(key, "SS010", this.error); - byte[] ivBytes = SecurityUtils.GetHexa(IV, "SS010", this.error); - if (this.HasError()) + + byte[] encryptedBytes = setUp(symmetricStreamAlgorithm, key, IV, input, true); + if (this.HasError()) { return null; } + + + return Base64.ToBase64String(encryptedBytes); + + } + + /// + /// Decrypts the given encrypted text with a stream encryption algorithm + /// + /// string SymmetrcStreamAlgorithm enum, algorithm name + /// string SymmetricBlockMode enum, mode name + /// String Hexa IV (nonce) for those algorithms that uses, ignored if not + /// string Base64 encrypted text with the given algorithm and parameters + /// plain text UTF-8 + [SecuritySafeCritical] + public string DoDecrypt(string symmetricStreamAlgorithm, string key, string IV, + string encryptedInput) + { + this.error.cleanError(); + + /*******INPUT VERIFICATION - BEGIN*******/ + SecurityUtils.validateStringInput("symmetricStreamAlgorithm", symmetricStreamAlgorithm, this.error); + SecurityUtils.validateStringInput("key", key, this.error); + SecurityUtils.validateStringInput("encryptedInput", encryptedInput, this.error); + if (this.HasError()) { return ""; }; + /*******INPUT VERIFICATION - END*******/ + + byte[] input = null; + try + { + input = Base64.Decode(encryptedInput); + } + catch (Exception e) { + this.error.setError("SS001", e.Message); return ""; } - KeyParameter keyParam = new KeyParameter(keyBytes); - if (SymmetricStreamAlgorithmUtils.usesIV(algorithm, this.GetError())) - { - if (!this.GetError().existsError()) - { - ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, ivBytes); - try - { - engine.Init(false, keyParamWithIV); - }catch(Exception e) - { - this.error.setError("SS011", e.Message); - return ""; - } - } - } - else - { - try + + byte[] decryptedBytes = setUp(symmetricStreamAlgorithm, key, IV, input, false); + if (this.HasError()) { return null; } + + EncodingUtil eu = new EncodingUtil(); + String result = eu.getString(decryptedBytes); + if (eu.HasError()) + { + this.error = eu.GetError(); + return ""; + } + return result.Trim(); + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + + + /// + /// Buils the StreamCipher + /// + /// SymmetrcStreamAlgorithm enum, algorithm name + /// IStreamCipher with the algorithm Stream Engine + private IStreamCipher getCipherEngine(SymmetricStreamAlgorithm algorithm) + { + + IStreamCipher engine = null; + + switch (algorithm) + { + case SymmetricStreamAlgorithm.RC4: + engine = new RC4Engine(); + break; + case SymmetricStreamAlgorithm.HC128: + engine = new HC128Engine(); + break; + case SymmetricStreamAlgorithm.HC256: + engine = new HC256Engine(); + break; + case SymmetricStreamAlgorithm.SALSA20: + engine = new Salsa20Engine(); + break; + case SymmetricStreamAlgorithm.CHACHA20: + engine = new ChaChaEngine(); + break; + case SymmetricStreamAlgorithm.XSALSA20: + engine = new XSalsa20Engine(); + break; + case SymmetricStreamAlgorithm.ISAAC: + engine = new IsaacEngine(); + break; + case SymmetricStreamAlgorithm.VMPC: + engine = new VmpcEngine(); + break; + default: + this.GetError().setError("SS005", "Cipher " + algorithm + " not recognised."); + break; + } + return engine; + + } + + private byte[] setUp(String symmetricStreamAlgorithm, string key, string IV, byte[] input, bool toEncrypt) + { + byte[] keyBytes = SecurityUtils.HexaToByte(key, this.error); + byte[] ivBytes = SecurityUtils.HexaToByte(IV, this.error); + SymmetricStreamAlgorithm algorithm = SymmetricStreamAlgorithmUtils + .getSymmetricStreamAlgorithm(symmetricStreamAlgorithm, this.error); + if (this.HasError()) { return null; } + + return encrypt(algorithm, keyBytes, ivBytes, input, toEncrypt); + + } + + private byte[] encrypt(SymmetricStreamAlgorithm algorithm, byte[] key, byte[] IV, byte[] input, bool toEncrypt) + { + IStreamCipher engine = getCipherEngine(algorithm); + if (this.HasError()) { return null; } + + + KeyParameter keyParam = new KeyParameter(key); + + try + { + if (SymmetricStreamAlgorithmUtils.usesIV(algorithm, this.error)) { - engine.Init(false, keyParam); - }catch(Exception e) + ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, IV); + engine.Init(toEncrypt, keyParamWithIV); + } + else { - this.error.setError("SS012", e.Message); - return ""; + engine.Init(toEncrypt, keyParam); } - } - byte[] input = Base64.Decode(encryptedInput); - byte[] output = new byte[input.Length]; - engine.ProcessBytes(input, 0, input.Length, output, 0); - if (output == null || output.Length == 0) - { - this.GetError().setError("SS006", "Stream decryption exception"); - return ""; - } - this.GetError().cleanError(); - EncodingUtil eu = new EncodingUtil(); - this.error = eu.GetError(); - return eu.getString(output); - } - - - /********EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - - - /// - /// Buils the StreamCipher - /// - /// SymmetrcStreamAlgorithm enum, algorithm name - /// IStreamCipher with the algorithm Stream Engine - private IStreamCipher getCipherEngine(SymmetricStreamAlgorithm algorithm) - { - - IStreamCipher engine = null; - - switch (algorithm) - { - case SymmetricStreamAlgorithm.RC4: - engine = new RC4Engine(); - break; - case SymmetricStreamAlgorithm.HC128: - engine = new HC128Engine(); - break; - case SymmetricStreamAlgorithm.HC256: - engine = new HC256Engine(); - break; - case SymmetricStreamAlgorithm.SALSA20: - engine = new Salsa20Engine(); - break; - case SymmetricStreamAlgorithm.CHACHA20: - engine = new ChaChaEngine(); - break; - case SymmetricStreamAlgorithm.XSALSA20: - engine = new XSalsa20Engine(); - break; - case SymmetricStreamAlgorithm.ISAAC: - engine = new IsaacEngine(); - break; - case SymmetricStreamAlgorithm.VMPC: - engine = new VmpcEngine(); - break; - default: - this.GetError().setError("SS005", "Cipher " + algorithm + " not recognised."); - break; - } - return engine; - - } - - } + } + catch (Exception e) + { + this.error.setError("SS003", e.Message); + return null; + } + + + byte[] output = new byte[input.Length]; + try + { + engine.ProcessBytes(input, 0, input.Length, output, 0); + } + catch (Exception e) + { + this.error.setError("SS004", e.Message); + return null; + } + return output; + } + + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockAlgorithm.cs index a36b4e250..9b65810be 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockAlgorithm.cs @@ -8,12 +8,12 @@ namespace GeneXusCryptography.SymmetricUtils { - /// - /// Implements SymmetricBlockAlgorithm enumerated - /// - [SecuritySafeCritical] - public enum SymmetricBlockAlgorithm - { + /// + /// Implements SymmetricBlockAlgorithm enumerated + /// + [SecuritySafeCritical] + public enum SymmetricBlockAlgorithm + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #pragma warning disable CA1707 // Identifiers should not contain underscores NONE, AES, BLOWFISH, CAMELLIA, CAST5, CAST6, DES, TRIPLEDES, DSTU7624_128, DSTU7624_256, DSTU7624_512, GOST28147, NOEKEON, RC2, RC532, RC564, RC6, RIJNDAEL_128, RIJNDAEL_160, RIJNDAEL_192, RIJNDAEL_224, RIJNDAEL_256, SEED, SERPENT, SKIPJACK, SM4, TEA, THREEFISH_256, THREEFISH_512, THREEFISH_1024, TWOFISH, XTEA @@ -21,327 +21,327 @@ public enum SymmetricBlockAlgorithm #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } - /// - /// Implements SymmetricBlockAlgorithm associated functions - /// - [SecuritySafeCritical] - public static class SymmetricBlockAlgorithmUtils - { - /// - /// Mapping between string name and SymmetricBlockAlgorithm enum representation - /// - /// string symmetricBlockAlgorithm - /// Error type for error management - /// SymmetricBlockAlgorithm enum representaton - public static SymmetricBlockAlgorithm getSymmetricBlockAlgorithm(string symmetricBlockAlgorithm, Error error) - { - if(error == null) return SymmetricBlockAlgorithm.NONE; - if(symmetricBlockAlgorithm == null) + /// + /// Implements SymmetricBlockAlgorithm associated functions + /// + [SecuritySafeCritical] + public static class SymmetricBlockAlgorithmUtils + { + /// + /// Mapping between string name and SymmetricBlockAlgorithm enum representation + /// + /// string symmetricBlockAlgorithm + /// Error type for error management + /// SymmetricBlockAlgorithm enum representaton + public static SymmetricBlockAlgorithm getSymmetricBlockAlgorithm(string symmetricBlockAlgorithm, Error error) + { + if (error == null) return SymmetricBlockAlgorithm.NONE; + if (symmetricBlockAlgorithm == null) { - error.setError("SB001", "Unrecognized SymmetricBlockAlgorithm"); + error.setError("SBA05", "Unrecognized SymmetricBlockAlgorithm"); return SymmetricBlockAlgorithm.NONE; } switch (symmetricBlockAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "AES": - return SymmetricBlockAlgorithm.AES; - case "BLOWFISH": - return SymmetricBlockAlgorithm.BLOWFISH; - case "CAMELLIA": - return SymmetricBlockAlgorithm.CAMELLIA; - case "CAST5": - return SymmetricBlockAlgorithm.CAST5; - case "CAST6": - return SymmetricBlockAlgorithm.CAST6; - case "DES": - return SymmetricBlockAlgorithm.DES; - case "TRIPLEDES": - return SymmetricBlockAlgorithm.TRIPLEDES; - case "DSTU7624_128": - return SymmetricBlockAlgorithm.DSTU7624_128; - case "DSTU7624_256": - return SymmetricBlockAlgorithm.DSTU7624_256; - case "DSTU7624_512": - return SymmetricBlockAlgorithm.DSTU7624_512; - case "GOST28147": - return SymmetricBlockAlgorithm.GOST28147; - case "NOEKEON": - return SymmetricBlockAlgorithm.NOEKEON; - case "RC2": - return SymmetricBlockAlgorithm.RC2; - case "RC6": - return SymmetricBlockAlgorithm.RC6; - case "RC532": - return SymmetricBlockAlgorithm.RC532; - case "RC564": - return SymmetricBlockAlgorithm.RC564; - case "RIJNDAEL_128": - return SymmetricBlockAlgorithm.RIJNDAEL_128; - case "RIJNDAEL_160": - return SymmetricBlockAlgorithm.RIJNDAEL_160; - case "RIJNDAEL_192": - return SymmetricBlockAlgorithm.RIJNDAEL_192; - case "RIJNDAEL_224": - return SymmetricBlockAlgorithm.RIJNDAEL_224; - case "RIJNDAEL_256": - return SymmetricBlockAlgorithm.RIJNDAEL_256; - case "SEED": - return SymmetricBlockAlgorithm.SEED; - case "SERPENT": - return SymmetricBlockAlgorithm.SERPENT; - case "SKIPJACK": - return SymmetricBlockAlgorithm.SKIPJACK; - case "SM4": - return SymmetricBlockAlgorithm.SM4; - case "THREEFISH_256": - return SymmetricBlockAlgorithm.THREEFISH_256; - case "THREEFISH_512": - return SymmetricBlockAlgorithm.THREEFISH_512; - case "THREEFISH_1024": - return SymmetricBlockAlgorithm.THREEFISH_1024; - case "TWOFISH": - return SymmetricBlockAlgorithm.TWOFISH; - case "XTEA": - return SymmetricBlockAlgorithm.XTEA; - case "TEA": - return SymmetricBlockAlgorithm.TEA; - default: - error.setError("SB001", "Unrecognized SymmetricBlockAlgorithm"); - return SymmetricBlockAlgorithm.NONE; - } + { + case "AES": + return SymmetricBlockAlgorithm.AES; + case "BLOWFISH": + return SymmetricBlockAlgorithm.BLOWFISH; + case "CAMELLIA": + return SymmetricBlockAlgorithm.CAMELLIA; + case "CAST5": + return SymmetricBlockAlgorithm.CAST5; + case "CAST6": + return SymmetricBlockAlgorithm.CAST6; + case "DES": + return SymmetricBlockAlgorithm.DES; + case "TRIPLEDES": + return SymmetricBlockAlgorithm.TRIPLEDES; + case "DSTU7624_128": + return SymmetricBlockAlgorithm.DSTU7624_128; + case "DSTU7624_256": + return SymmetricBlockAlgorithm.DSTU7624_256; + case "DSTU7624_512": + return SymmetricBlockAlgorithm.DSTU7624_512; + case "GOST28147": + return SymmetricBlockAlgorithm.GOST28147; + case "NOEKEON": + return SymmetricBlockAlgorithm.NOEKEON; + case "RC2": + return SymmetricBlockAlgorithm.RC2; + case "RC6": + return SymmetricBlockAlgorithm.RC6; + case "RC532": + return SymmetricBlockAlgorithm.RC532; + case "RC564": + return SymmetricBlockAlgorithm.RC564; + case "RIJNDAEL_128": + return SymmetricBlockAlgorithm.RIJNDAEL_128; + case "RIJNDAEL_160": + return SymmetricBlockAlgorithm.RIJNDAEL_160; + case "RIJNDAEL_192": + return SymmetricBlockAlgorithm.RIJNDAEL_192; + case "RIJNDAEL_224": + return SymmetricBlockAlgorithm.RIJNDAEL_224; + case "RIJNDAEL_256": + return SymmetricBlockAlgorithm.RIJNDAEL_256; + case "SEED": + return SymmetricBlockAlgorithm.SEED; + case "SERPENT": + return SymmetricBlockAlgorithm.SERPENT; + case "SKIPJACK": + return SymmetricBlockAlgorithm.SKIPJACK; + case "SM4": + return SymmetricBlockAlgorithm.SM4; + case "THREEFISH_256": + return SymmetricBlockAlgorithm.THREEFISH_256; + case "THREEFISH_512": + return SymmetricBlockAlgorithm.THREEFISH_512; + case "THREEFISH_1024": + return SymmetricBlockAlgorithm.THREEFISH_1024; + case "TWOFISH": + return SymmetricBlockAlgorithm.TWOFISH; + case "XTEA": + return SymmetricBlockAlgorithm.XTEA; + case "TEA": + return SymmetricBlockAlgorithm.TEA; + default: + error.setError("SBA01", "Unrecognized SymmetricBlockAlgorithm"); + return SymmetricBlockAlgorithm.NONE; + } - } + } - /// - /// Mapping between SymmetricBlockAlgorithm enum representation and string name - /// - /// SymmetricBlockAlgorithm enum, algorithm name - /// Error type for error management - /// value of SymmetricBlockAlgorithm in string - public static string valueOf(SymmetricBlockAlgorithm symmetricBlockAlgorithm, Error error) - { + /// + /// Mapping between SymmetricBlockAlgorithm enum representation and string name + /// + /// SymmetricBlockAlgorithm enum, algorithm name + /// Error type for error management + /// value of SymmetricBlockAlgorithm in string + public static string valueOf(SymmetricBlockAlgorithm symmetricBlockAlgorithm, Error error) + { if (error == null) return "SymmetricBlockAlgorithm"; switch (symmetricBlockAlgorithm) - { - case SymmetricBlockAlgorithm.AES: - return "AES"; - case SymmetricBlockAlgorithm.BLOWFISH: - return "BLOWFISH"; - case SymmetricBlockAlgorithm.CAMELLIA: - return "CAMELLIA"; - case SymmetricBlockAlgorithm.CAST5: - return "CAST5"; - case SymmetricBlockAlgorithm.CAST6: - return "CAST6"; - case SymmetricBlockAlgorithm.DES: - return "DES"; - case SymmetricBlockAlgorithm.TRIPLEDES: - return "TRIPLEDES"; - case SymmetricBlockAlgorithm.DSTU7624_128: - return "DSTU7624_128"; - case SymmetricBlockAlgorithm.DSTU7624_256: - return "DSTU7624_256"; - case SymmetricBlockAlgorithm.DSTU7624_512: - return "DSTU7624_512"; - case SymmetricBlockAlgorithm.GOST28147: - return "GOST28147"; - case SymmetricBlockAlgorithm.NOEKEON: - return "NOEKEON"; - case SymmetricBlockAlgorithm.RC2: - return "RC2"; - case SymmetricBlockAlgorithm.RC6: - return "RC6"; - case SymmetricBlockAlgorithm.RC532: - return "RC532"; - case SymmetricBlockAlgorithm.RC564: - return "RC564"; - case SymmetricBlockAlgorithm.RIJNDAEL_128: - return "RIJNDAEL_128"; - case SymmetricBlockAlgorithm.RIJNDAEL_160: - return "RIJNDAEL_160"; - case SymmetricBlockAlgorithm.RIJNDAEL_192: - return "RIJNDAEL_192"; - case SymmetricBlockAlgorithm.RIJNDAEL_224: - return "RIJNDAEL_224"; - case SymmetricBlockAlgorithm.RIJNDAEL_256: - return "RIJNDAEL_256"; - case SymmetricBlockAlgorithm.SEED: - return "SEED"; - case SymmetricBlockAlgorithm.SERPENT: - return "SERPENT"; - case SymmetricBlockAlgorithm.SKIPJACK: - return "SKIPJACK"; - case SymmetricBlockAlgorithm.SM4: - return "SM4"; - case SymmetricBlockAlgorithm.THREEFISH_256: - return "THREEFISH_256"; - case SymmetricBlockAlgorithm.THREEFISH_512: - return "THREEFISH_512"; - case SymmetricBlockAlgorithm.THREEFISH_1024: - return "THREEFISH_1024"; - case SymmetricBlockAlgorithm.TWOFISH: - return "TWOFISH"; - case SymmetricBlockAlgorithm.XTEA: - return "XTEA"; - case SymmetricBlockAlgorithm.TEA: - return "TEA"; - default: - error.setError("SB002", "Unrecognized SymmetricBlockAlgorithm"); - return "SymmetricBlockAlgorithm"; - } - } + { + case SymmetricBlockAlgorithm.AES: + return "AES"; + case SymmetricBlockAlgorithm.BLOWFISH: + return "BLOWFISH"; + case SymmetricBlockAlgorithm.CAMELLIA: + return "CAMELLIA"; + case SymmetricBlockAlgorithm.CAST5: + return "CAST5"; + case SymmetricBlockAlgorithm.CAST6: + return "CAST6"; + case SymmetricBlockAlgorithm.DES: + return "DES"; + case SymmetricBlockAlgorithm.TRIPLEDES: + return "TRIPLEDES"; + case SymmetricBlockAlgorithm.DSTU7624_128: + return "DSTU7624_128"; + case SymmetricBlockAlgorithm.DSTU7624_256: + return "DSTU7624_256"; + case SymmetricBlockAlgorithm.DSTU7624_512: + return "DSTU7624_512"; + case SymmetricBlockAlgorithm.GOST28147: + return "GOST28147"; + case SymmetricBlockAlgorithm.NOEKEON: + return "NOEKEON"; + case SymmetricBlockAlgorithm.RC2: + return "RC2"; + case SymmetricBlockAlgorithm.RC6: + return "RC6"; + case SymmetricBlockAlgorithm.RC532: + return "RC532"; + case SymmetricBlockAlgorithm.RC564: + return "RC564"; + case SymmetricBlockAlgorithm.RIJNDAEL_128: + return "RIJNDAEL_128"; + case SymmetricBlockAlgorithm.RIJNDAEL_160: + return "RIJNDAEL_160"; + case SymmetricBlockAlgorithm.RIJNDAEL_192: + return "RIJNDAEL_192"; + case SymmetricBlockAlgorithm.RIJNDAEL_224: + return "RIJNDAEL_224"; + case SymmetricBlockAlgorithm.RIJNDAEL_256: + return "RIJNDAEL_256"; + case SymmetricBlockAlgorithm.SEED: + return "SEED"; + case SymmetricBlockAlgorithm.SERPENT: + return "SERPENT"; + case SymmetricBlockAlgorithm.SKIPJACK: + return "SKIPJACK"; + case SymmetricBlockAlgorithm.SM4: + return "SM4"; + case SymmetricBlockAlgorithm.THREEFISH_256: + return "THREEFISH_256"; + case SymmetricBlockAlgorithm.THREEFISH_512: + return "THREEFISH_512"; + case SymmetricBlockAlgorithm.THREEFISH_1024: + return "THREEFISH_1024"; + case SymmetricBlockAlgorithm.TWOFISH: + return "TWOFISH"; + case SymmetricBlockAlgorithm.XTEA: + return "XTEA"; + case SymmetricBlockAlgorithm.TEA: + return "TEA"; + default: + error.setError("SBA02", "Unrecognized SymmetricBlockAlgorithm"); + return "SymmetricBlockAlgorithm"; + } + } - /// - /// Gets the block size lenght for the given algorithm - /// - /// SymmetricBlockAlgorithm enum, algorithm name - /// Error type for error management - /// the specific block size for the algorithm, algorithm unknown if 0 - public static int getBlockSize(SymmetricBlockAlgorithm algorithm, Error error) - { + /// + /// Gets the block size lenght for the given algorithm + /// + /// SymmetricBlockAlgorithm enum, algorithm name + /// Error type for error management + /// the specific block size for the algorithm, algorithm unknown if 0 + public static int getBlockSize(SymmetricBlockAlgorithm algorithm, Error error) + { if (error == null) return 0; - switch (algorithm) - { + switch (algorithm) + { - case SymmetricBlockAlgorithm.BLOWFISH: - case SymmetricBlockAlgorithm.CAST5: - case SymmetricBlockAlgorithm.DES: - case SymmetricBlockAlgorithm.GOST28147: - case SymmetricBlockAlgorithm.RC2: - case SymmetricBlockAlgorithm.RC532: - case SymmetricBlockAlgorithm.SKIPJACK: - case SymmetricBlockAlgorithm.XTEA: - case SymmetricBlockAlgorithm.TRIPLEDES: - case SymmetricBlockAlgorithm.TEA: - return 64; - case SymmetricBlockAlgorithm.AES: - case SymmetricBlockAlgorithm.CAMELLIA: - case SymmetricBlockAlgorithm.CAST6: - case SymmetricBlockAlgorithm.NOEKEON: - case SymmetricBlockAlgorithm.RC564: - case SymmetricBlockAlgorithm.RC6: - case SymmetricBlockAlgorithm.SEED: - case SymmetricBlockAlgorithm.SERPENT: - case SymmetricBlockAlgorithm.SM4: - case SymmetricBlockAlgorithm.TWOFISH: - case SymmetricBlockAlgorithm.DSTU7624_128: - case SymmetricBlockAlgorithm.RIJNDAEL_128: - return 128; - case SymmetricBlockAlgorithm.RIJNDAEL_160: - return 160; - case SymmetricBlockAlgorithm.RIJNDAEL_192: - return 192; - case SymmetricBlockAlgorithm.RIJNDAEL_224: - return 224; - case SymmetricBlockAlgorithm.DSTU7624_256: - case SymmetricBlockAlgorithm.RIJNDAEL_256: - case SymmetricBlockAlgorithm.THREEFISH_256: - return 256; - case SymmetricBlockAlgorithm.DSTU7624_512: - case SymmetricBlockAlgorithm.THREEFISH_512: - return 512; - case SymmetricBlockAlgorithm.THREEFISH_1024: - return 1024; - default: - error.setError("SB003", "Unrecognized SymmetricBlockAlgorithm"); - return 0; - } - } + case SymmetricBlockAlgorithm.BLOWFISH: + case SymmetricBlockAlgorithm.CAST5: + case SymmetricBlockAlgorithm.DES: + case SymmetricBlockAlgorithm.GOST28147: + case SymmetricBlockAlgorithm.RC2: + case SymmetricBlockAlgorithm.RC532: + case SymmetricBlockAlgorithm.SKIPJACK: + case SymmetricBlockAlgorithm.XTEA: + case SymmetricBlockAlgorithm.TRIPLEDES: + case SymmetricBlockAlgorithm.TEA: + return 64; + case SymmetricBlockAlgorithm.AES: + case SymmetricBlockAlgorithm.CAMELLIA: + case SymmetricBlockAlgorithm.CAST6: + case SymmetricBlockAlgorithm.NOEKEON: + case SymmetricBlockAlgorithm.RC564: + case SymmetricBlockAlgorithm.RC6: + case SymmetricBlockAlgorithm.SEED: + case SymmetricBlockAlgorithm.SERPENT: + case SymmetricBlockAlgorithm.SM4: + case SymmetricBlockAlgorithm.TWOFISH: + case SymmetricBlockAlgorithm.DSTU7624_128: + case SymmetricBlockAlgorithm.RIJNDAEL_128: + return 128; + case SymmetricBlockAlgorithm.RIJNDAEL_160: + return 160; + case SymmetricBlockAlgorithm.RIJNDAEL_192: + return 192; + case SymmetricBlockAlgorithm.RIJNDAEL_224: + return 224; + case SymmetricBlockAlgorithm.DSTU7624_256: + case SymmetricBlockAlgorithm.RIJNDAEL_256: + case SymmetricBlockAlgorithm.THREEFISH_256: + return 256; + case SymmetricBlockAlgorithm.DSTU7624_512: + case SymmetricBlockAlgorithm.THREEFISH_512: + return 512; + case SymmetricBlockAlgorithm.THREEFISH_1024: + return 1024; + default: + error.setError("SBA03", "Unrecognized SymmetricBlockAlgorithm"); + return 0; + } + } - /// - /// Gets the key lenght for the given algorithm - /// - /// SymmetricBlockAlgorithm enum, algorithm name - /// Error type for error management - /// array int with fixed length 3 with key, if array[0]=0 is range, else fixed values - public static int[] getKeySize(SymmetricBlockAlgorithm algorithm, Error error) - { - int[] keySize = new int[3]; + /// + /// Gets the key lenght for the given algorithm + /// + /// SymmetricBlockAlgorithm enum, algorithm name + /// Error type for error management + /// array int with fixed length 3 with key, if array[0]=0 is range, else fixed values + public static int[] getKeySize(SymmetricBlockAlgorithm algorithm, Error error) + { + int[] keySize = new int[3]; - switch (algorithm) - { + switch (algorithm) + { - case SymmetricBlockAlgorithm.BLOWFISH: - keySize[0] = 0; - keySize[1] = 448; - break; - case SymmetricBlockAlgorithm.CAMELLIA: - case SymmetricBlockAlgorithm.SERPENT: - case SymmetricBlockAlgorithm.TWOFISH: - keySize[0] = 128; - keySize[1] = 192; - keySize[2] = 256; - break; - case SymmetricBlockAlgorithm.AES: - case SymmetricBlockAlgorithm.CAST6: - case SymmetricBlockAlgorithm.RC6: - case SymmetricBlockAlgorithm.RIJNDAEL_128: - case SymmetricBlockAlgorithm.RIJNDAEL_160: - case SymmetricBlockAlgorithm.RIJNDAEL_192: - case SymmetricBlockAlgorithm.RIJNDAEL_224: - case SymmetricBlockAlgorithm.RIJNDAEL_256: - keySize[0] = 0; - keySize[1] = 256; - break; - case SymmetricBlockAlgorithm.DES: - keySize[0] = 64; - break; - case SymmetricBlockAlgorithm.TRIPLEDES: - keySize[0] = 128; - keySize[1] = 192; - break; - case SymmetricBlockAlgorithm.DSTU7624_128: - case SymmetricBlockAlgorithm.DSTU7624_256: - case SymmetricBlockAlgorithm.DSTU7624_512: - keySize[0] = 128; - keySize[1] = 256; - keySize[2] = 512; - break; - case SymmetricBlockAlgorithm.GOST28147: - keySize[0] = 256; - break; - case SymmetricBlockAlgorithm.NOEKEON: - case SymmetricBlockAlgorithm.SEED: - case SymmetricBlockAlgorithm.SM4: - case SymmetricBlockAlgorithm.XTEA: - case SymmetricBlockAlgorithm.TEA: - keySize[0] = 128; - break; - case SymmetricBlockAlgorithm.RC2: - keySize[0] = 0; - keySize[1] = 1024; - break; - case SymmetricBlockAlgorithm.RC532: - case SymmetricBlockAlgorithm.RC564: - case SymmetricBlockAlgorithm.SKIPJACK: - case SymmetricBlockAlgorithm.CAST5: - keySize[0] = 0; - keySize[1] = 128; - break; - case SymmetricBlockAlgorithm.THREEFISH_256: - case SymmetricBlockAlgorithm.THREEFISH_512: - case SymmetricBlockAlgorithm.THREEFISH_1024: - keySize[0] = 128; - keySize[1] = 512; - keySize[2] = 1024; - break; - /*default: - error.setError("SB004", "Unrecognized SymmetricBlockAlgorithm");*/ - } - return keySize; - } + case SymmetricBlockAlgorithm.BLOWFISH: + keySize[0] = 0; + keySize[1] = 448; + break; + case SymmetricBlockAlgorithm.CAMELLIA: + case SymmetricBlockAlgorithm.SERPENT: + case SymmetricBlockAlgorithm.TWOFISH: + keySize[0] = 128; + keySize[1] = 192; + keySize[2] = 256; + break; + case SymmetricBlockAlgorithm.AES: + case SymmetricBlockAlgorithm.CAST6: + case SymmetricBlockAlgorithm.RC6: + case SymmetricBlockAlgorithm.RIJNDAEL_128: + case SymmetricBlockAlgorithm.RIJNDAEL_160: + case SymmetricBlockAlgorithm.RIJNDAEL_192: + case SymmetricBlockAlgorithm.RIJNDAEL_224: + case SymmetricBlockAlgorithm.RIJNDAEL_256: + keySize[0] = 0; + keySize[1] = 256; + break; + case SymmetricBlockAlgorithm.DES: + keySize[0] = 64; + break; + case SymmetricBlockAlgorithm.TRIPLEDES: + keySize[0] = 128; + keySize[1] = 192; + break; + case SymmetricBlockAlgorithm.DSTU7624_128: + case SymmetricBlockAlgorithm.DSTU7624_256: + case SymmetricBlockAlgorithm.DSTU7624_512: + keySize[0] = 128; + keySize[1] = 256; + keySize[2] = 512; + break; + case SymmetricBlockAlgorithm.GOST28147: + keySize[0] = 256; + break; + case SymmetricBlockAlgorithm.NOEKEON: + case SymmetricBlockAlgorithm.SEED: + case SymmetricBlockAlgorithm.SM4: + case SymmetricBlockAlgorithm.XTEA: + case SymmetricBlockAlgorithm.TEA: + keySize[0] = 128; + break; + case SymmetricBlockAlgorithm.RC2: + keySize[0] = 0; + keySize[1] = 1024; + break; + case SymmetricBlockAlgorithm.RC532: + case SymmetricBlockAlgorithm.RC564: + case SymmetricBlockAlgorithm.SKIPJACK: + case SymmetricBlockAlgorithm.CAST5: + keySize[0] = 0; + keySize[1] = 128; + break; + case SymmetricBlockAlgorithm.THREEFISH_256: + case SymmetricBlockAlgorithm.THREEFISH_512: + case SymmetricBlockAlgorithm.THREEFISH_1024: + keySize[0] = 128; + keySize[1] = 512; + keySize[2] = 1024; + break; + //default: + //error.setError("SBA04", "Unrecognized SymmetricBlockAlgorithm");*/ + } + return keySize; + } - /// - /// Manage Enumerable enum - /// - /// SymmetricBlockAlgorithm enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(SymmetricBlockAlgorithm)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// SymmetricBlockAlgorithm enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(SymmetricBlockAlgorithm)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockMode.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockMode.cs index 5cfd47326..8374f45ee 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockMode.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockMode.cs @@ -8,12 +8,12 @@ namespace GeneXusCryptography.SymmetricUtils { - /// - /// Implements SymmetricBlockMode enumerated - /// - [SecuritySafeCritical] - public enum SymmetricBlockMode - { + /// + /// Implements SymmetricBlockMode enumerated + /// + [SecuritySafeCritical] + public enum SymmetricBlockMode + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #pragma warning disable CA1707 // Identifiers should not contain underscores NONE, ECB, CBC, CFB, CTR, CTS, GOFB, OFB, OPENPGPCFB, SIC, /* AEAD */ AEAD_EAX, AEAD_GCM, AEAD_KCCM, AEAD_CCM @@ -22,142 +22,142 @@ public enum SymmetricBlockMode } - /// - /// Implements SymmetricBlockMode associated functions - /// - [SecuritySafeCritical] - public static class SymmetricBlockModeUtils - { - /// - /// Mapping between string name and SymmetricBlockMode enum representation - /// - /// string symmetricBlockMode - /// Error type for error management - /// SymmetricBlockMode enum representation - public static SymmetricBlockMode getSymmetricBlockMode(string symmetricBlockMode, Error error) - { + /// + /// Implements SymmetricBlockMode associated functions + /// + [SecuritySafeCritical] + public static class SymmetricBlockModeUtils + { + /// + /// Mapping between string name and SymmetricBlockMode enum representation + /// + /// string symmetricBlockMode + /// Error type for error management + /// SymmetricBlockMode enum representation + public static SymmetricBlockMode getSymmetricBlockMode(string symmetricBlockMode, Error error) + { if (error == null) return SymmetricBlockMode.NONE; - if(symmetricBlockMode == null) + if (symmetricBlockMode == null) { - error.setError("SB005", "Unrecognized SymmetricBlockMode"); + error.setError("SBM04", "Unrecognized SymmetricBlockMode"); return SymmetricBlockMode.NONE; } switch (symmetricBlockMode.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "ECB": - return SymmetricBlockMode.ECB; - case "CBC": - return SymmetricBlockMode.CBC; - case "CFB": - return SymmetricBlockMode.CFB; - case "CTS": - return SymmetricBlockMode.CTS; - case "GOFB": - return SymmetricBlockMode.GOFB; - case "OFB": - return SymmetricBlockMode.OFB; - case "OPENPGPCFB": - return SymmetricBlockMode.OPENPGPCFB; - case "SIC": - return SymmetricBlockMode.SIC; - case "CTR": - return SymmetricBlockMode.CTR; + { + case "ECB": + return SymmetricBlockMode.ECB; + case "CBC": + return SymmetricBlockMode.CBC; + case "CFB": + return SymmetricBlockMode.CFB; + case "CTS": + return SymmetricBlockMode.CTS; + case "GOFB": + return SymmetricBlockMode.GOFB; + case "OFB": + return SymmetricBlockMode.OFB; + case "OPENPGPCFB": + return SymmetricBlockMode.OPENPGPCFB; + case "SIC": + return SymmetricBlockMode.SIC; + case "CTR": + return SymmetricBlockMode.CTR; - /* AEAD */ - case "AEAD_EAX": - return SymmetricBlockMode.AEAD_EAX; - case "AEAD_GCM": - return SymmetricBlockMode.AEAD_GCM; - case "AEAD_KCCM": - return SymmetricBlockMode.AEAD_KCCM; - case "AEAD_CCM": - return SymmetricBlockMode.AEAD_CCM; - default: - error.setError("SB005", "Unrecognized SymmetricBlockMode"); - return SymmetricBlockMode.NONE; - } - } + /* AEAD */ + case "AEAD_EAX": + return SymmetricBlockMode.AEAD_EAX; + case "AEAD_GCM": + return SymmetricBlockMode.AEAD_GCM; + case "AEAD_KCCM": + return SymmetricBlockMode.AEAD_KCCM; + case "AEAD_CCM": + return SymmetricBlockMode.AEAD_CCM; + default: + error.setError("SBM01", "Unrecognized SymmetricBlockMode"); + return SymmetricBlockMode.NONE; + } + } - /// - /// Mapping between SymmetricBlockMode enum representation and string name - /// - /// SymmetricBlockMode enum, mode name - /// Error type for error management - /// SymmetricBlockMode name value in string - public static string valueOf(SymmetricBlockMode symmetricBlockMode, Error error) - { + /// + /// Mapping between SymmetricBlockMode enum representation and string name + /// + /// SymmetricBlockMode enum, mode name + /// Error type for error management + /// SymmetricBlockMode name value in string + public static string valueOf(SymmetricBlockMode symmetricBlockMode, Error error) + { if (error == null) return "Unrecognized operation mode"; switch (symmetricBlockMode) - { - case SymmetricBlockMode.ECB: - return "ECB"; - case SymmetricBlockMode.CBC: - return "CBC"; - case SymmetricBlockMode.CFB: - return "CFB"; - case SymmetricBlockMode.CTS: - return "CTS"; - case SymmetricBlockMode.GOFB: - return "GOFB"; - case SymmetricBlockMode.OFB: - return "OFB"; - case SymmetricBlockMode.OPENPGPCFB: - return "OPENPGPCFB"; - case SymmetricBlockMode.SIC: - return "SIC"; - case SymmetricBlockMode.CTR: - return "CTR"; + { + case SymmetricBlockMode.ECB: + return "ECB"; + case SymmetricBlockMode.CBC: + return "CBC"; + case SymmetricBlockMode.CFB: + return "CFB"; + case SymmetricBlockMode.CTS: + return "CTS"; + case SymmetricBlockMode.GOFB: + return "GOFB"; + case SymmetricBlockMode.OFB: + return "OFB"; + case SymmetricBlockMode.OPENPGPCFB: + return "OPENPGPCFB"; + case SymmetricBlockMode.SIC: + return "SIC"; + case SymmetricBlockMode.CTR: + return "CTR"; - /* AEAD */ + /* AEAD */ - case SymmetricBlockMode.AEAD_EAX: - return "AEAD_EAX"; - case SymmetricBlockMode.AEAD_GCM: - return "AEAD_GCM"; - case SymmetricBlockMode.AEAD_KCCM: - return "AEAD_KCCM"; - case SymmetricBlockMode.AEAD_CCM: - return "AEAD_CCM"; - default: - error.setError("SB006", "Unrecognized SymmetricBlockMode"); - return "Unrecognized operation mode"; - } - } + case SymmetricBlockMode.AEAD_EAX: + return "AEAD_EAX"; + case SymmetricBlockMode.AEAD_GCM: + return "AEAD_GCM"; + case SymmetricBlockMode.AEAD_KCCM: + return "AEAD_KCCM"; + case SymmetricBlockMode.AEAD_CCM: + return "AEAD_CCM"; + default: + error.setError("SBM02", "Unrecognized SymmetricBlockMode"); + return "Unrecognized operation mode"; + } + } - /// - /// Find if a given mode is AEAD type - /// - /// SymmetricBlockMode enum, mode name - /// Error type for error management - /// boolean true if operation mode is AEAD type - public static bool isAEAD(SymmetricBlockMode symmetricBlockMode, Error error) - { + /// + /// Find if a given mode is AEAD type + /// + /// SymmetricBlockMode enum, mode name + /// Error type for error management + /// boolean true if operation mode is AEAD type + public static bool isAEAD(SymmetricBlockMode symmetricBlockMode, Error error) + { if (error == null) return false; - switch (symmetricBlockMode) - { - case SymmetricBlockMode.AEAD_EAX: - case SymmetricBlockMode.AEAD_GCM: - case SymmetricBlockMode.AEAD_KCCM: - case SymmetricBlockMode.AEAD_CCM: - return true; - default: - error.setError("SB007", "Unrecognized Symmetric AEAD BlockMode"); - return false; - } - } + switch (symmetricBlockMode) + { + case SymmetricBlockMode.AEAD_EAX: + case SymmetricBlockMode.AEAD_GCM: + case SymmetricBlockMode.AEAD_KCCM: + case SymmetricBlockMode.AEAD_CCM: + return true; + default: + error.setError("SBM03", "Unrecognized Symmetric AEAD BlockMode"); + return false; + } + } - /// - /// Manage Enumerable enum - /// - /// SymmetricBlockMode enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(SymmetricBlockMode)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// SymmetricBlockMode enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(SymmetricBlockMode)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockPadding.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockPadding.cs index 6a42f48f8..08385df93 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockPadding.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricBlockPadding.cs @@ -8,96 +8,96 @@ namespace GeneXusCryptography.SymmetricUtils { - /// - /// Implements SymmetricBlockPadding enumerated - /// - [SecuritySafeCritical] - public enum SymmetricBlockPadding - { + /// + /// Implements SymmetricBlockPadding enumerated + /// + [SecuritySafeCritical] + public enum SymmetricBlockPadding + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - NOPADDING, PKCS7PADDING, ISO10126D2PADDING, X923PADDING, ISO7816D4PADDING, ZEROBYTEPADDING, WITHCTS + NOPADDING, PKCS7PADDING, ISO10126D2PADDING, X923PADDING, ISO7816D4PADDING, ZEROBYTEPADDING, WITHCTS #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - } + } - /// - /// Implements SymmetricBlockPadding associated functions - /// - [SecuritySafeCritical] - public static class SymmetricBlockPaddingUtils - { - /// - /// Mapping between string name and SymmetricBlockPadding enum representation - /// - /// string symmetricBlockPadding - /// Error type for error management - /// SymmetricBlockPadding enum representation - public static SymmetricBlockPadding getSymmetricBlockPadding(string symmetricBlockPadding, Error error) - { + /// + /// Implements SymmetricBlockPadding associated functions + /// + [SecuritySafeCritical] + public static class SymmetricBlockPaddingUtils + { + /// + /// Mapping between string name and SymmetricBlockPadding enum representation + /// + /// string symmetricBlockPadding + /// Error type for error management + /// SymmetricBlockPadding enum representation + public static SymmetricBlockPadding getSymmetricBlockPadding(string symmetricBlockPadding, Error error) + { if (error == null) return SymmetricBlockPadding.NOPADDING; - if(symmetricBlockPadding == null) + if (symmetricBlockPadding == null) { - error.setError("SB008", "Unrecognized SymmetricBlockPadding"); + error.setError("SBP03", "Unrecognized SymmetricBlockPadding"); return SymmetricBlockPadding.NOPADDING; } - switch (symmetricBlockPadding.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "NOPADDING": - return SymmetricBlockPadding.NOPADDING; - case "PKCS7PADDING": - return SymmetricBlockPadding.PKCS7PADDING; - case "ISO10126D2PADDING": - return SymmetricBlockPadding.ISO10126D2PADDING; - case "X923PADDING": - return SymmetricBlockPadding.X923PADDING; - case "ISO7816D4PADDING": - return SymmetricBlockPadding.ISO7816D4PADDING; - case "ZEROBYTEPADDING": - return SymmetricBlockPadding.ZEROBYTEPADDING; - case "WITHCTS": - return SymmetricBlockPadding.WITHCTS; - default: - error.setError("SB008", "Unrecognized SymmetricBlockPadding"); - return SymmetricBlockPadding.NOPADDING; - } - } - /// - /// Mapping between SymmetricBlockPadding enum representation and string name - /// - /// SymmetricBlockPadding enum, padding name - /// Error type for error management - /// string name value of SymmetricBlockPadding - public static string valueOf(SymmetricBlockPadding symmetricBlockPadding, Error error) - { - if(error == null) return "Unrecognized block padding"; + switch (symmetricBlockPadding.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) + { + case "NOPADDING": + return SymmetricBlockPadding.NOPADDING; + case "PKCS7PADDING": + return SymmetricBlockPadding.PKCS7PADDING; + case "ISO10126D2PADDING": + return SymmetricBlockPadding.ISO10126D2PADDING; + case "X923PADDING": + return SymmetricBlockPadding.X923PADDING; + case "ISO7816D4PADDING": + return SymmetricBlockPadding.ISO7816D4PADDING; + case "ZEROBYTEPADDING": + return SymmetricBlockPadding.ZEROBYTEPADDING; + case "WITHCTS": + return SymmetricBlockPadding.WITHCTS; + default: + error.setError("SBP01", "Unrecognized SymmetricBlockPadding"); + return SymmetricBlockPadding.NOPADDING; + } + } + /// + /// Mapping between SymmetricBlockPadding enum representation and string name + /// + /// SymmetricBlockPadding enum, padding name + /// Error type for error management + /// string name value of SymmetricBlockPadding + public static string valueOf(SymmetricBlockPadding symmetricBlockPadding, Error error) + { + if (error == null) return "Unrecognized block padding"; switch (symmetricBlockPadding) - { - case SymmetricBlockPadding.NOPADDING: - return "NOPADDING"; - case SymmetricBlockPadding.PKCS7PADDING: - return "PKCS7PADDING"; - case SymmetricBlockPadding.ISO10126D2PADDING: - return "ISO10126D2PADDING"; - case SymmetricBlockPadding.X923PADDING: - return "X923PADDING"; - case SymmetricBlockPadding.ISO7816D4PADDING: - return "ISO7816D4PADDING"; - case SymmetricBlockPadding.ZEROBYTEPADDING: - return "ZEROBYTEPADDING"; - case SymmetricBlockPadding.WITHCTS: - return "WITHCTS"; - default: - error.setError("SB009", "Unrecognized SymmetricBlockPadding"); - return "Unrecognized block padding"; - } - } - /// - /// Manage Enumerable enum - /// - /// SymmetricBlockPadding enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(SymmetricBlockPadding)).Cast(); - } - } + { + case SymmetricBlockPadding.NOPADDING: + return "NOPADDING"; + case SymmetricBlockPadding.PKCS7PADDING: + return "PKCS7PADDING"; + case SymmetricBlockPadding.ISO10126D2PADDING: + return "ISO10126D2PADDING"; + case SymmetricBlockPadding.X923PADDING: + return "X923PADDING"; + case SymmetricBlockPadding.ISO7816D4PADDING: + return "ISO7816D4PADDING"; + case SymmetricBlockPadding.ZEROBYTEPADDING: + return "ZEROBYTEPADDING"; + case SymmetricBlockPadding.WITHCTS: + return "WITHCTS"; + default: + error.setError("SBP02", "Unrecognized SymmetricBlockPadding"); + return "Unrecognized block padding"; + } + } + /// + /// Manage Enumerable enum + /// + /// SymmetricBlockPadding enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(SymmetricBlockPadding)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricStreamAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricStreamAlgorithm.cs index 2ddcd2c29..203be27da 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricStreamAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/SymmetricUtils/SymmetricStreamAlgorithm.cs @@ -8,179 +8,179 @@ namespace GeneXusCryptography.SymmetricUtils { - /// - /// Implements SymmetricStreamAlgorithm enumerated - /// - [SecuritySafeCritical] - public enum SymmetricStreamAlgorithm - { + /// + /// Implements SymmetricStreamAlgorithm enumerated + /// + [SecuritySafeCritical] + public enum SymmetricStreamAlgorithm + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - NONE, RC4, HC128, HC256, CHACHA20, SALSA20, XSALSA20, ISAAC, VMPC + NONE, RC4, HC128, HC256, CHACHA20, SALSA20, XSALSA20, ISAAC, VMPC #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - } + } - /// - /// Implements SymmetricStreamAlgorithm associated functions - /// - [SecuritySafeCritical] - public static class SymmetricStreamAlgorithmUtils - { - /// - /// Mapping between String name and SymmetricStreamAlgorithm enum representation - /// - /// String symmetricStreamAlgorithm - /// Error type for error management - /// SymmetricStreamAlgorithm enum representation - public static SymmetricStreamAlgorithm getSymmetricStreamAlgorithm(String symmetricStreamAlgorithm, Error error) - { + /// + /// Implements SymmetricStreamAlgorithm associated functions + /// + [SecuritySafeCritical] + public static class SymmetricStreamAlgorithmUtils + { + /// + /// Mapping between String name and SymmetricStreamAlgorithm enum representation + /// + /// String symmetricStreamAlgorithm + /// Error type for error management + /// SymmetricStreamAlgorithm enum representation + public static SymmetricStreamAlgorithm getSymmetricStreamAlgorithm(String symmetricStreamAlgorithm, Error error) + { if (error == null) return SymmetricStreamAlgorithm.NONE; - if( symmetricStreamAlgorithm == null) + if (symmetricStreamAlgorithm == null) { - error.setError("SS001", "Unrecognized SymmetricStreamAlgorithm"); + error.setError("SSA05", "Unrecognized SymmetricStreamAlgorithm"); return SymmetricStreamAlgorithm.NONE; } switch (symmetricStreamAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "RC4": - return SymmetricStreamAlgorithm.RC4; - case "HC128": - return SymmetricStreamAlgorithm.HC128; - case "HC256": - return SymmetricStreamAlgorithm.HC256; - case "CHACHA20": - return SymmetricStreamAlgorithm.CHACHA20; - case "SALSA20": - return SymmetricStreamAlgorithm.SALSA20; - case "XSALSA20": - return SymmetricStreamAlgorithm.XSALSA20; - case "ISAAC": - return SymmetricStreamAlgorithm.ISAAC; - case "VMPC": - return SymmetricStreamAlgorithm.VMPC; - default: - error.setError("SS001", "Unrecognized SymmetricStreamAlgorithm"); - return SymmetricStreamAlgorithm.NONE; - } - } - /// - /// Mapping between SymmetricStreamAlgorithm enum representationa and String name - /// - /// SymmetrcStreamAlgorithm enum, algorithm name - /// Error type for error management - /// String SymmetrcStreamAlgorithm name value - public static String valueOf(SymmetricStreamAlgorithm symmetrcStreamAlgorithm, Error error) - { - if(error == null) return "Unrecognized algorithm"; + { + case "RC4": + return SymmetricStreamAlgorithm.RC4; + case "HC128": + return SymmetricStreamAlgorithm.HC128; + case "HC256": + return SymmetricStreamAlgorithm.HC256; + case "CHACHA20": + return SymmetricStreamAlgorithm.CHACHA20; + case "SALSA20": + return SymmetricStreamAlgorithm.SALSA20; + case "XSALSA20": + return SymmetricStreamAlgorithm.XSALSA20; + case "ISAAC": + return SymmetricStreamAlgorithm.ISAAC; + case "VMPC": + return SymmetricStreamAlgorithm.VMPC; + default: + error.setError("SSA01", "Unrecognized SymmetricStreamAlgorithm"); + return SymmetricStreamAlgorithm.NONE; + } + } + /// + /// Mapping between SymmetricStreamAlgorithm enum representationa and String name + /// + /// SymmetrcStreamAlgorithm enum, algorithm name + /// Error type for error management + /// String SymmetrcStreamAlgorithm name value + public static String valueOf(SymmetricStreamAlgorithm symmetrcStreamAlgorithm, Error error) + { + if (error == null) return "Unrecognized algorithm"; switch (symmetrcStreamAlgorithm) - { - case SymmetricStreamAlgorithm.RC4: - return "RC4"; - case SymmetricStreamAlgorithm.HC128: - return "HC128"; - case SymmetricStreamAlgorithm.HC256: - return "HC256"; - case SymmetricStreamAlgorithm.CHACHA20: - return "CHACHA20"; - case SymmetricStreamAlgorithm.SALSA20: - return "SALSA20"; - case SymmetricStreamAlgorithm.XSALSA20: - return "XSALSA20"; - case SymmetricStreamAlgorithm.ISAAC: - return "ISAAC"; - case SymmetricStreamAlgorithm.VMPC: - return "VMPC"; - default: - error.setError("SS002", "Unrecognized SymmetricStreamAlgorithm"); - return "Unrecognized algorithm"; - } - } + { + case SymmetricStreamAlgorithm.RC4: + return "RC4"; + case SymmetricStreamAlgorithm.HC128: + return "HC128"; + case SymmetricStreamAlgorithm.HC256: + return "HC256"; + case SymmetricStreamAlgorithm.CHACHA20: + return "CHACHA20"; + case SymmetricStreamAlgorithm.SALSA20: + return "SALSA20"; + case SymmetricStreamAlgorithm.XSALSA20: + return "XSALSA20"; + case SymmetricStreamAlgorithm.ISAAC: + return "ISAAC"; + case SymmetricStreamAlgorithm.VMPC: + return "VMPC"; + default: + error.setError("SSA02", "Unrecognized SymmetricStreamAlgorithm"); + return "Unrecognized algorithm"; + } + } - /// - /// Returns key size for the algorithm in bits - /// - /// SymmetrcStreamAlgorithm enum, algorithm name - /// Error type for error management - /// array int with fixed length 3 with key, if array[0]=0 is range, else fixed values - public static int[] getKeySize(SymmetricStreamAlgorithm algorithm, Error error) - { + /// + /// Returns key size for the algorithm in bits + /// + /// SymmetrcStreamAlgorithm enum, algorithm name + /// Error type for error management + /// array int with fixed length 3 with key, if array[0]=0 is range, else fixed values + public static int[] getKeySize(SymmetricStreamAlgorithm algorithm, Error error) + { if (error == null) return null; - int[] keySize = new int[3]; - switch (algorithm) - { - case SymmetricStreamAlgorithm.RC4: - keySize[0] = 0; - keySize[1] = 40; - keySize[2] = 2048; - break; - case SymmetricStreamAlgorithm.HC128: - keySize[0] = 1; - keySize[1] = 128; - break; - case SymmetricStreamAlgorithm.HC256: - case SymmetricStreamAlgorithm.XSALSA20: - keySize[0] = 1; - keySize[1] = 256; - break; - case SymmetricStreamAlgorithm.CHACHA20: - case SymmetricStreamAlgorithm.SALSA20: - keySize[0] = 1; - keySize[1] = 128; - keySize[2] = 256; - break; - case SymmetricStreamAlgorithm.ISAAC: - keySize[0] = 0; - keySize[1] = 32; - keySize[2] = 8192; - break; - case SymmetricStreamAlgorithm.VMPC: - keySize[0] = 0; - keySize[1] = 8; - keySize[2] = 6144; - break; - default: - error.setError("SS003", "Unrecognized SymmetricStreamAlgorithm"); - break; - } - return keySize; - } + int[] keySize = new int[3]; + switch (algorithm) + { + case SymmetricStreamAlgorithm.RC4: + keySize[0] = 0; + keySize[1] = 40; + keySize[2] = 2048; + break; + case SymmetricStreamAlgorithm.HC128: + keySize[0] = 1; + keySize[1] = 128; + break; + case SymmetricStreamAlgorithm.HC256: + case SymmetricStreamAlgorithm.XSALSA20: + keySize[0] = 1; + keySize[1] = 256; + break; + case SymmetricStreamAlgorithm.CHACHA20: + case SymmetricStreamAlgorithm.SALSA20: + keySize[0] = 1; + keySize[1] = 128; + keySize[2] = 256; + break; + case SymmetricStreamAlgorithm.ISAAC: + keySize[0] = 0; + keySize[1] = 32; + keySize[2] = 8192; + break; + case SymmetricStreamAlgorithm.VMPC: + keySize[0] = 0; + keySize[1] = 8; + keySize[2] = 6144; + break; + default: + error.setError("SSA03", "Unrecognized SymmetricStreamAlgorithm"); + break; + } + return keySize; + } - /// - /// Containsinformation about algorithm's IV - /// - /// SymmetrcStreamAlgorithm enum, algorithm name - /// Error type for error management - /// true if the algorithm uses an IV or nonce, false if it do not - internal static bool usesIV(SymmetricStreamAlgorithm algorithm, Error error) - { - switch (algorithm) - { - case SymmetricStreamAlgorithm.RC4: - case SymmetricStreamAlgorithm.HC128: - case SymmetricStreamAlgorithm.ISAAC: - return false; - case SymmetricStreamAlgorithm.HC256: - case SymmetricStreamAlgorithm.SALSA20: - case SymmetricStreamAlgorithm.CHACHA20: - case SymmetricStreamAlgorithm.XSALSA20: - case SymmetricStreamAlgorithm.VMPC: - return true; - default: - error.setError("SS007", "Unrecognized SymmetricStreamAlgorithm"); - return true; - } + /// + /// Containsinformation about algorithm's IV + /// + /// SymmetrcStreamAlgorithm enum, algorithm name + /// Error type for error management + /// true if the algorithm uses an IV or nonce, false if it do not + internal static bool usesIV(SymmetricStreamAlgorithm algorithm, Error error) + { + switch (algorithm) + { + case SymmetricStreamAlgorithm.RC4: + case SymmetricStreamAlgorithm.HC128: + case SymmetricStreamAlgorithm.ISAAC: + return false; + case SymmetricStreamAlgorithm.HC256: + case SymmetricStreamAlgorithm.SALSA20: + case SymmetricStreamAlgorithm.CHACHA20: + case SymmetricStreamAlgorithm.XSALSA20: + case SymmetricStreamAlgorithm.VMPC: + return true; + default: + error.setError("SSA04", "Unrecognized SymmetricStreamAlgorithm"); + return true; + } - } + } - /// - /// Manage Enumerable enum - /// - /// SymmetricStreamAlgorithm enum - /// Enum values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(SymmetricStreamAlgorithm)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// SymmetricStreamAlgorithm enum + /// Enum values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(SymmetricStreamAlgorithm)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj index f85a43d8e..02dd37267 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj @@ -19,7 +19,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWT/JWTCreator.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWT/JWTCreator.cs index f89b5dc53..e414fc9c8 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWT/JWTCreator.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWT/JWTCreator.cs @@ -18,739 +18,755 @@ namespace GeneXusJWT.GenexusJWT { - [SecuritySafeCritical] - public class JWTCreator : SecurityAPIObject, IJWTObject - { - private int counter; + [SecuritySafeCritical] + public class JWTCreator : SecurityAPIObject, IJWTObject + { + private int counter; + + + [SecuritySafeCritical] + public JWTCreator() : base() + { + + + EncodingUtil eu = new EncodingUtil(); + eu.setEncoding("UTF8"); + this.counter = 0; + /***Config to Debug - Delete on Release version!!!***/ + Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; + } + + /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + [SecuritySafeCritical] + public string DoCreate(string algorithm, PrivateClaims privateClaims, JWTOptions options) + { + this.error.cleanError(); + return Create_Aux(algorithm, privateClaims, options, null, true); + } + + [SecuritySafeCritical] + public string DoCreateFromJSON(string algorithm, string json, JWTOptions options) + { + this.error.cleanError(); + return Create_Aux(algorithm, null, options, json, false); + } + + [SecuritySafeCritical] + public bool DoVerify(String token, String expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options) + { + this.error.cleanError(); + return DoVerify(token, expectedAlgorithm, privateClaims, options, true, true); + } + + [SecuritySafeCritical] + public bool DoVerifyJustSignature(String token, String expectedAlgorithm, JWTOptions options) + { + this.error.cleanError(); + return DoVerify(token, expectedAlgorithm, null, options, false, false); + } + + [SecuritySafeCritical] + public bool DoVerifySignature(String token, String expectedAlgorithm, JWTOptions options) + { + this.error.cleanError(); + return DoVerify(token, expectedAlgorithm, null, options, false, true); + } + + [SecuritySafeCritical] + public string GetPayload(string token) + { + this.error.cleanError(); + string res = ""; + try + { + res = getTokenPart(token, "payload"); + } + catch (Exception e) + { + this.error.setError("JW001", e.Message); + return ""; + } + return res; + + } + [SecuritySafeCritical] + public string GetHeader(string token) + { + this.error.cleanError(); + string res = ""; + try + { + res = getTokenPart(token, "header"); + } + catch (Exception e) + { + this.error.setError("JW002", e.Message); + return ""; + } + return res; + } + + [SecuritySafeCritical] + public string GetTokenID(string token) + { + this.error.cleanError(); + string res = ""; + try + { - [SecuritySafeCritical] - public JWTCreator() : base() - { + res = getTokenPart(token, "id"); + } + catch (Exception e) + { + this.error.setError("JW003", e.Message); + return ""; + } + return res; + } - EncodingUtil eu = new EncodingUtil(); - eu.setEncoding("UTF8"); - this.counter = 0; - /***Config to Debug - Delete on Release version!!!***/ - Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; - } + /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ - /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ - [SecuritySafeCritical] - public string DoCreate(string algorithm, PrivateClaims privateClaims, JWTOptions options) - { - this.error.cleanError(); - if(options == null) + [SecuritySafeCritical] + private string Create_Aux(string algorithm, PrivateClaims privateClaims, JWTOptions options, string payloadString, bool hasClaims) + { + if (options == null) { this.error.setError("JW000", "Options parameter is null"); return ""; } - if(privateClaims == null) + JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm(algorithm, this.error); + if (this.HasError()) { - this.error.setError("JW000", "PrivateClaims parameter is null"); return ""; } - if (options.HasError()) - { - this.error = options.GetError(); - return ""; - } - JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm(algorithm, this.error); - if (this.HasError()) - { - return ""; - } - if (this.HasError()) - { - return ""; - } - /***Hack to support 1024 RSA key lengths - BEGIN***/ - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS256"] = 1024; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS512"] = 1024; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS384"] = 1024; - /***Hack to support 1024 RSA key lengths - END***/ - - /***Hack to support 192 ECDSA key lengths - BEGIN***/ - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES256"] = 112; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES512"] = 112; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES384"] = 112; - /***Hack to support 192 ECDSA key lengths - END***/ - - JwtPayload payload = doBuildPayload(privateClaims, options); - - SecurityKey genericKey = null; - if (JWTAlgorithmUtils.isPrivate(alg)) - { - - PrivateKeyManager key = options.GetPrivateKey(); - if (key.HasError()) - { - this.error = key.GetError(); - return ""; - } - if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "RSA")) - { - try - { - genericKey = new RsaSecurityKey((RSA)key.getPrivateKeyForJWT()); - }catch(Exception) + /***Hack to support 1024 RSA key lengths - BEGIN***/ + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS256"] = 1024; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS512"] = 1024; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS384"] = 1024; + /***Hack to support 1024 RSA key lengths - END***/ + + /***Hack to support 192 ECDSA key lengths - BEGIN***/ + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES256"] = 112; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES512"] = 112; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES384"] = 112; + /***Hack to support 192 ECDSA key lengths - END***/ + JwtPayload payload = null; + if (hasClaims) + { + if (privateClaims == null) + { + this.error.setError("JW000", "PrivateClaims parameter is null"); + return ""; + } + payload = doBuildPayload(privateClaims, options); + } + else + { + try + { + payload = JwtPayload.Deserialize(payloadString); + } + catch (Exception ex) + { + this.error.setError("", ex.Message); + return ""; + } + } + + + SecurityKey genericKey = null; + if (JWTAlgorithmUtils.isPrivate(alg)) + { + + PrivateKeyManager key = options.GetPrivateKey(); + if (key.HasError()) + { + this.error = key.GetError(); + return ""; + } + if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "RSA")) + { + try { - this.error = key.GetError(); - return ""; + genericKey = new RsaSecurityKey((RSA)key.getPrivateKeyForJWT()); } + catch (Exception) + { + this.error = key.GetError(); + return ""; + } + + } + else if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "ECDSA")) + { + try + { + genericKey = new ECDsaSecurityKey((ECDsa)key.getPrivateKeyForJWT()); + } + catch (Exception) + { + this.error = key.GetError(); + return ""; + } + } + else + { + this.error.setError("JW012", "Not recognized key algorithm"); + return ""; + } + if (genericKey == null) + { + this.error = key.GetError(); + return ""; + } + } + else + { + SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret()); + genericKey = symKey; + } - } - else if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "ECDSA")) - { - try { - genericKey = new ECDsaSecurityKey((ECDsa)key.getPrivateKeyForJWT()); - } - catch (Exception) - { - this.error = key.GetError(); - return ""; - } - } - else - { - this.error.setError("JW012", "Not recognized key algorithm"); - return ""; - } - if (genericKey == null) - { - this.error = key.GetError(); - return ""; - } - } - else - { - SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret()); - genericKey = symKey; - } - - SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error); - if (this.HasError()) - { - - return ""; - } - - string signedJwt = ""; - try - { - - JwtHeader header = new JwtHeader(signingCredentials); - if (!options.GetHeaderParameters().IsEmpty()) - { - AddHeaderParameters(header, options); - } - - JwtSecurityToken secToken = new JwtSecurityToken(header, payload); - JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); - signedJwt = handler.WriteToken(secToken); - } - catch (Exception e) - { - - this.error.setError("JW003", "key size: " + /*genericKey.KeySize.ToString()*/e.Message + e.StackTrace); - - return ""; - } - - return signedJwt; - } - - [SecuritySafeCritical] - public bool DoVerify(String token, String expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options) - { - if(options == null) + SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error); + if (this.HasError()) { - this.error.setError("JW000", "Options parameter is null"); - return false; + + return ""; } - return DoVerify(token, expectedAlgorithm, privateClaims, options, true, true); - } - [SecuritySafeCritical] - public bool DoVerifyJustSignature(String token, String expectedAlgorithm, JWTOptions options) - { + string signedJwt = ""; + try + { + + JwtHeader header = new JwtHeader(signingCredentials); + if (!options.GetHeaderParameters().IsEmpty()) + { + AddHeaderParameters(header, options); + } + + JwtSecurityToken secToken = new JwtSecurityToken(header, payload); + JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); + signedJwt = handler.WriteToken(secToken); + } + catch (Exception e) + { + + this.error.setError("JW003", "key size: " + /*genericKey.KeySize.ToString()*/e.Message + e.StackTrace); + + return ""; + } + + return signedJwt; + } + + [SecuritySafeCritical] + private bool DoVerify(string token, string expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options, bool verifyClaims, bool verifyRegClaims) + { if (options == null) { - this.error.setError("JW000", "Options parameter is null"); + this.error.setError("JW004", "Options parameter is null"); + return false; + } + JWTAlgorithm expectedJWTAlgorithm = JWTAlgorithmUtils.getJWTAlgorithm(expectedAlgorithm, this.error); + if (this.HasError()) + { return false; } - return DoVerify(token, expectedAlgorithm, null, options, false, false); - } - [SecuritySafeCritical] - public bool DoVerifySignature(String token, String expectedAlgorithm, JWTOptions options) - { - if (options == null) + /***Hack to support 1024 RSA key lengths - BEGIN***/ + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS256"] = 1024; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS512"] = 1024; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS384"] = 1024; + /***Hack to support 1024 RSA key lengths - END***/ + + /***Hack to support 192 ECDSA key lengths - BEGIN***/ + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha256"] = 112; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha512"] = 112; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha384"] = 112; + /***Hack to support 192 ECDSA key lengths - END***/ + + /***Hack to support 192 ECDSA key lengths - BEGIN***/ + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES256"] = 112; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES512"] = 112; + AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES384"] = 112; + /***Hack to support 192 ECDSA key lengths - END***/ + + + JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); + JwtSecurityToken jwtToken = new JwtSecurityToken(token); + if (isRevoqued(jwtToken, options)) { - this.error.setError("JW000", "Options parameter is null"); return false; } - return DoVerify(token, expectedAlgorithm, null, options, false, true); - } - - [SecuritySafeCritical] - public string GetPayload(string token) - { - - string res = ""; - try - { - res = getTokenPart(token, "payload"); - } - catch (Exception e) - { - this.error.setError("JW009", e.Message); - return ""; - } - return res; - - } - - [SecuritySafeCritical] - public string GetHeader(string token) - { - string res = ""; - try - { - res = getTokenPart(token, "header"); - } - catch (Exception e) - { - this.error.setError("JW010", e.Message); - return ""; - } - return res; - } - - [SecuritySafeCritical] - public string GetTokenID(string token) - { - string res = ""; - try - { - - res = getTokenPart(token, "id"); - } - catch (Exception e) - { - this.error.setError("JW011", e.Message); - return ""; - } - return res; - } - - - /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - [SecuritySafeCritical] - private bool DoVerify(string token, string expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options, bool verifyClaims, bool verifyRegClaims) - { - this.error.cleanError(); - if (options.HasError()) - { - this.error = options.GetError(); - return false; - } - JWTAlgorithm expectedJWTAlgorithm = JWTAlgorithmUtils.getJWTAlgorithm(expectedAlgorithm, this.error); - if (this.HasError()) - { - return false; - } - - /***Hack to support 1024 RSA key lengths - BEGIN***/ - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS256"] = 1024; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS512"] = 1024; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS384"] = 1024; - /***Hack to support 1024 RSA key lengths - END***/ - - /***Hack to support 192 ECDSA key lengths - BEGIN***/ - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha256"] = 112; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha512"] = 112; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha384"] = 112; - /***Hack to support 192 ECDSA key lengths - END***/ - - /***Hack to support 192 ECDSA key lengths - BEGIN***/ - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES256"] = 112; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES512"] = 112; - AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES384"] = 112; - /***Hack to support 192 ECDSA key lengths - END***/ - - - JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); - JwtSecurityToken jwtToken = new JwtSecurityToken(token); - if (isRevoqued(jwtToken, options)) - { - return false; - } - if (verifyRegClaims) - { - if (!validateRegisteredClaims(jwtToken, options)) - { - return false; - } - } - if (verifyClaims) - { - if (!verifyPrivateClaims(jwtToken, privateClaims, options) || !VerifyHeader(jwtToken, options)) - { - return false; - } - } - //if validates all registered claims and it is not on revocation list - TokenValidationParameters parms = new TokenValidationParameters(); - parms.ValidateLifetime = false; - parms.ValidateAudience = false; - parms.ValidateIssuer = false; - parms.ValidateActor = false; - JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm_forVerification(jwtToken.Header.Alg, this.error); - if (this.HasError()) - { - return false; - } - if (JWTAlgorithmUtils.getJWTAlgorithm(jwtToken.Header.Alg, this.error) != expectedJWTAlgorithm || this.HasError()) - { - this.error.setError("JW008", "Expected algorithm does not match token algorithm"); - return false; - } - SecurityKey genericKey = null; - if (JWTAlgorithmUtils.isPrivate(alg)) - { - - - CertificateX509 cert = options.GetCertificate(); - if (cert.HasError()) - { - this.error = cert.GetError(); - return false; - } - if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "RSA")) - { - try { - genericKey = new RsaSecurityKey((RSA)cert.getPublicKeyJWT()); - } - catch (Exception) - { - this.error = cert.GetError(); - return false; - } - - } - else if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "ECDSA")) - { - try - { - genericKey = new ECDsaSecurityKey((ECDsa)cert.getPublicKeyJWT()); - } - catch (Exception) - { - this.error = cert.GetError(); - return false; - } - - } - else - { - this.error.setError("JW013", "Not recognized key algorithm"); - return false; - } - - } - else - { - SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret()); - genericKey = symKey; - } - genericKey.KeyId = "256"; - - SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error); - parms.IssuerSigningKey = genericKey; - SecurityToken validatedToken; - try - { - handler.ValidateToken(token, parms, out validatedToken); - } - catch (Exception e) - { - this.error.setError("JW004", e.Message); - - return false; - } - return true; - - - - } - - - private JwtPayload doBuildPayload(PrivateClaims privateClaims, JWTOptions options) - { - JwtPayload payload = new JwtPayload(); - // ****START BUILD PAYLOAD****// - // Adding private claims - List privateC = privateClaims.getAllClaims(); - foreach (Claim privateClaim in privateC) - { - - if (privateClaim.getNestedClaims() != null) - { - - payload.Add(privateClaim.getKey(), privateClaim.getNestedClaims().getNestedMap()); - } - else - { - System.Security.Claims.Claim netPrivateClaim = null; - object obj = privateClaim.getValue(); - if (obj.GetType() == typeof(string)) - { - netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), (string)privateClaim.getValue()); - } - else if (obj.GetType() == typeof(int)) - { - int value = (int)obj; - netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Integer32); - } - else if (obj.GetType() == typeof(long)) - { - long value = (long)obj; - netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Integer64); - } - else if (obj.GetType() == typeof(double)) - { - double value = (double)obj; - netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Double); - }else if (obj.GetType() == typeof(bool)) + if (verifyRegClaims) + { + if (!validateRegisteredClaims(jwtToken, options)) + { + return false; + } + } + if (verifyClaims) + { + if (!verifyPrivateClaims(jwtToken, privateClaims, options) || !VerifyHeader(jwtToken, options)) + { + return false; + } + } + //if validates all registered claims and it is not on revocation list + TokenValidationParameters parms = new TokenValidationParameters(); + parms.ValidateLifetime = false; + parms.ValidateAudience = false; + parms.ValidateIssuer = false; + parms.ValidateActor = false; + JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm_forVerification(jwtToken.Header.Alg, this.error); + if (this.HasError()) + { + return false; + } + if (JWTAlgorithmUtils.getJWTAlgorithm(jwtToken.Header.Alg, this.error) != expectedJWTAlgorithm || this.HasError()) + { + this.error.setError("JW008", "Expected algorithm does not match token algorithm"); + return false; + } + SecurityKey genericKey = null; + if (JWTAlgorithmUtils.isPrivate(alg)) + { + + + CertificateX509 cert = options.GetCertificate(); + if (cert.HasError()) + { + this.error = cert.GetError(); + return false; + } + if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "RSA")) + { + try + { + genericKey = new RsaSecurityKey((RSA)cert.getPublicKeyJWT()); + } + catch (Exception) + { + this.error = cert.GetError(); + return false; + } + + } + else if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "ECDSA")) + { + try + { + genericKey = new ECDsaSecurityKey((ECDsa)cert.getPublicKeyJWT()); + } + catch (Exception) + { + this.error = cert.GetError(); + return false; + } + + } + else + { + this.error.setError("JW015", "Not recognized key algorithm"); + return false; + } + + } + else + { + SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret()); + genericKey = symKey; + } + genericKey.KeyId = "256"; + + SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error); + parms.IssuerSigningKey = genericKey; + SecurityToken validatedToken; + try + { + handler.ValidateToken(token, parms, out validatedToken); + } + catch (Exception e) + { + this.error.setError("JW009", e.Message); + + return false; + } + return true; + + + + } + + + private JwtPayload doBuildPayload(PrivateClaims privateClaims, JWTOptions options) + { + JwtPayload payload = new JwtPayload(); + // ****START BUILD PAYLOAD****// + // Adding private claims + List privateC = privateClaims.getAllClaims(); + foreach (Claim privateClaim in privateC) + { + + if (privateClaim.getNestedClaims() != null) + { + + payload.Add(privateClaim.getKey(), privateClaim.getNestedClaims().getNestedMap()); + } + else + { + System.Security.Claims.Claim netPrivateClaim = null; + object obj = privateClaim.getValue(); + if (obj.GetType() == typeof(string)) + { + netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), (string)privateClaim.getValue()); + } + else if (obj.GetType() == typeof(int)) { - bool value = (bool)obj; - netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Boolean); + int value = (int)obj; + netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Integer32); + } + else if (obj.GetType() == typeof(long)) + { + long value = (long)obj; + netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Integer64); + } + else if (obj.GetType() == typeof(double)) + { + double value = (double)obj; + netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Double); + } + else if (obj.GetType() == typeof(bool)) + { + bool value = (bool)obj; + netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(System.Globalization.CultureInfo.InvariantCulture), System.Security.Claims.ClaimValueTypes.Boolean); + } + else + { + this.error.setError("JW016", "Unrecognized data type"); + } + + //System.Security.Claims.Claim netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), privateClaim.getValue()); + + payload.AddClaim(netPrivateClaim); + } + + } + // Adding public claims + if (options.hasPublicClaims()) + { + PublicClaims publicClaims = options.getAllPublicClaims(); + List publicC = publicClaims.getAllClaims(); + foreach (Claim publicClaim in publicC) + { + System.Security.Claims.Claim netPublicClaim = new System.Security.Claims.Claim(publicClaim.getKey(), (string)publicClaim.getValue()); + payload.AddClaim(netPublicClaim); + } + + } + // Adding registered claims + if (options.hasRegisteredClaims()) + { + RegisteredClaims registeredClaims = options.getAllRegisteredClaims(); + List registeredC = registeredClaims.getAllClaims(); + foreach (Claim registeredClaim in registeredC) + { + System.Security.Claims.Claim netRegisteredClaim; + + if (RegisteredClaimUtils.isTimeValidatingClaim(registeredClaim.getKey())) + { + + netRegisteredClaim = new System.Security.Claims.Claim(registeredClaim.getKey(), (string)registeredClaim.getValue(), System.Security.Claims.ClaimValueTypes.Integer32); } else { - this.error.setError("JW012", "Unrecognized data type"); + + netRegisteredClaim = new System.Security.Claims.Claim(registeredClaim.getKey(), (string)registeredClaim.getValue()); } - //System.Security.Claims.Claim netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), privateClaim.getValue()); - - payload.AddClaim(netPrivateClaim); - } - - } - // Adding public claims - if (options.hasPublicClaims()) - { - PublicClaims publicClaims = options.getAllPublicClaims(); - List publicC = publicClaims.getAllClaims(); - foreach (Claim publicClaim in publicC) - { - System.Security.Claims.Claim netPublicClaim = new System.Security.Claims.Claim(publicClaim.getKey(), (string)publicClaim.getValue()); - payload.AddClaim(netPublicClaim); - } - - } - // Adding registered claims - if (options.hasRegisteredClaims()) - { - RegisteredClaims registeredClaims = options.getAllRegisteredClaims(); - List registeredC = registeredClaims.getAllClaims(); - foreach (Claim registeredClaim in registeredC) - { - System.Security.Claims.Claim netRegisteredClaim; - - if (RegisteredClaimUtils.isTimeValidatingClaim(registeredClaim.getKey())) - { - - netRegisteredClaim = new System.Security.Claims.Claim(registeredClaim.getKey(), (string)registeredClaim.getValue(), System.Security.Claims.ClaimValueTypes.Integer32); - } - else - { - - netRegisteredClaim = new System.Security.Claims.Claim(registeredClaim.getKey(), (string)registeredClaim.getValue()); - } - - payload.AddClaim(netRegisteredClaim); - } - } - // ****END BUILD PAYLOAD****// - return payload; - } - - private bool validateRegisteredClaims(JwtSecurityToken jwtToken, JWTOptions options) - { - - - // Adding registered claims - if (options.hasRegisteredClaims()) - { - RegisteredClaims registeredClaims = options.getAllRegisteredClaims(); - List registeredC = registeredClaims.getAllClaims(); - foreach (Claim registeredClaim in registeredC) - { - string registeredClaimKey = registeredClaim.getKey(); - object registeredClaimValue = registeredClaim.getValue(); - if (RegisteredClaimUtils.exists(registeredClaimKey)) - { - if (!RegisteredClaimUtils.isTimeValidatingClaim(registeredClaimKey)) - { - if (!RegisteredClaimUtils.validateClaim(registeredClaimKey, (string)registeredClaimValue, 0, jwtToken, this.error)) - { - return false; - } - } - else - { - long customValidationTime = registeredClaims.getClaimCustomValidationTime(registeredClaimKey); - //int value = (int)registeredClaimValue; - if (!RegisteredClaimUtils.validateClaim(registeredClaimKey, (string)registeredClaimValue, customValidationTime, jwtToken, this.error)) - { - return false; - } - } - if (this.HasError()) - { - return false; - } - - - } - else - { - error.setError("JW002", registeredClaimKey + " wrong registered claim key"); - return false; - } - } - } - return true; - } - private static bool isRevoqued(JwtSecurityToken jwtToken, JWTOptions options) - { - RevocationList rList = options.getRevocationList(); - return rList.isInRevocationList(jwtToken.Payload.Jti); - } - - private String getTokenPart(string token, String part) - { - JwtSecurityToken jwtToken = new JwtSecurityToken(token); - - switch (part) - { - case "payload": - return jwtToken.Payload.SerializeToJson(); - case "header": - return jwtToken.Header.SerializeToJson(); - case "id": - return jwtToken.Payload.Jti; - default: - error.setError("JW007", "Unknown token segment"); - return ""; - } - - } - - private bool verifyPrivateClaims(JwtSecurityToken jwtToken, PrivateClaims privateClaims, JWTOptions options) - { - RegisteredClaims registeredClaims = options.getAllRegisteredClaims(); - PublicClaims publicClaims = options.getAllPublicClaims(); - if (privateClaims == null || privateClaims.isEmpty()) - { - return true; - } - string jsonPayload = jwtToken.Payload.SerializeToJson(); - Dictionary map = null; - try - { - map = JsonConvert.DeserializeObject>(jsonPayload); - } - catch (Exception) - { - this.error.setError("JW009", "Cannot parse JWT payload"); - return false; - } - this.counter = 0; - bool validation = verifyNestedClaims(privateClaims.getNestedMap(), map, registeredClaims, publicClaims); - int pClaimsCount = countingPrivateClaims(privateClaims.getNestedMap(), 0); - if (validation && !(this.counter == pClaimsCount)) - { - return false; - } - return validation; - } - - private bool verifyNestedClaims(Dictionary pclaimMap, Dictionary map, - RegisteredClaims registeredClaims, PublicClaims publicClaims) - { - List mapClaimKeyList = new List(map.Keys); - List pClaimKeyList = new List(pclaimMap.Keys); - if (pClaimKeyList.Count > pClaimKeyList.Count) - { - return false; - } - foreach (String mapKey in mapClaimKeyList) - { - - if (!isRegistered(mapKey, registeredClaims) && !isPublic(mapKey, publicClaims)) - { - this.counter++; - if (!pclaimMap.ContainsKey(mapKey)) - { - return false; - } - - object op = pclaimMap[mapKey]; - object ot = map[mapKey]; - Type opt = op.GetType(); - Type ott = ot.GetType(); - Type int16 = Type.GetType("System.Int16", false, true) ; - Type int32 = Type.GetType("System.Int32", false, true); - Type int64 = Type.GetType("System.Int64", false, true); - if ((opt == typeof(string)) && (ott == typeof(string))) - { - - if (!SecurityUtils.compareStrings(((string)op).Trim(), ((string)ot).Trim())) - { - return false; - } - } - - else if (((opt == int16) || (opt == int32) || (opt == int64)) && ((ott == int16) || (ott == int32) || (ott == int64))) - { - if (Convert.ToInt32(op, System.Globalization.CultureInfo.InvariantCulture) != Convert.ToInt32(ot, System.Globalization.CultureInfo.InvariantCulture)) - { - return false; - } - }else if(opt == typeof(bool)) - { - if(Convert.ToBoolean(op, System.Globalization.CultureInfo.InvariantCulture) != Convert.ToBoolean(ot, System.Globalization.CultureInfo.InvariantCulture)) + payload.AddClaim(netRegisteredClaim); + } + } + // ****END BUILD PAYLOAD****// + return payload; + } + + private bool validateRegisteredClaims(JwtSecurityToken jwtToken, JWTOptions options) + { + + + // Adding registered claims + if (options.hasRegisteredClaims()) + { + RegisteredClaims registeredClaims = options.getAllRegisteredClaims(); + List registeredC = registeredClaims.getAllClaims(); + foreach (Claim registeredClaim in registeredC) + { + string registeredClaimKey = registeredClaim.getKey(); + object registeredClaimValue = registeredClaim.getValue(); + if (RegisteredClaimUtils.exists(registeredClaimKey)) + { + if (!RegisteredClaimUtils.isTimeValidatingClaim(registeredClaimKey)) + { + if (!RegisteredClaimUtils.validateClaim(registeredClaimKey, (string)registeredClaimValue, 0, jwtToken, this.error)) + { + return false; + } + } + else + { + long customValidationTime = registeredClaims.getClaimCustomValidationTime(registeredClaimKey); + //int value = (int)registeredClaimValue; + if (!RegisteredClaimUtils.validateClaim(registeredClaimKey, (string)registeredClaimValue, customValidationTime, jwtToken, this.error)) + { + return false; + } + } + if (this.HasError()) { - return false; + return false; } - - } else if ((op.GetType() == typeof(Dictionary)) && (ot.GetType() == typeof(JObject))) - { - - - bool flag = verifyNestedClaims((Dictionary)op, ((JObject)ot).ToObject>(), - registeredClaims, publicClaims); - if (!flag) - { - return false; - } - } - else - { - return false; - } - } - } - return true; - } - - private void AddHeaderParameters(JwtHeader header, JWTOptions options) - { - HeaderParameters parameters = options.GetHeaderParameters(); - List list = parameters.GetAll(); - Dictionary map = parameters.GetMap(); - foreach (string s in list) - { - header.Add(s.Trim(), ((string)map[s]).Trim()); - } - } - - private static bool VerifyHeader(JwtSecurityToken jwtToken, JWTOptions options) - { - int claimsNumber = jwtToken.Header.Count; - HeaderParameters parameters = options.GetHeaderParameters(); - if (parameters.IsEmpty() && claimsNumber == 2) - { - return true; - } - if (parameters.IsEmpty() && claimsNumber > 2) - { - return false; - } - - List allParms = parameters.GetAll(); - if (claimsNumber != allParms.Count + 2) - { - return false; - } - Dictionary map = parameters.GetMap(); - - - foreach (string s in allParms) - { - - if (!jwtToken.Header.ContainsKey(s.Trim())) - { - return false; - } - - - string claimValue = null; - try - { - claimValue = (string)jwtToken.Header[s.Trim()]; - } - catch (Exception) - { - return false; - } - String optionsValue = ((string)map[s]).Trim(); - if (!SecurityUtils.compareStrings(claimValue, optionsValue.Trim())) - { - return false; - } - } - return true; - - } - - private static bool isRegistered(string claimKey, RegisteredClaims registeredClaims) - { - - List registeredClaimsList = registeredClaims.getAllClaims(); - foreach (Claim s in registeredClaimsList) - { - if (SecurityUtils.compareStrings(s.getKey().Trim(), claimKey.Trim())) - { - return true; - } - } - return false; - } - - private static bool isPublic(string claimKey, PublicClaims publicClaims) - { - List publicClaimsList = publicClaims.getAllClaims(); - foreach (Claim s in publicClaimsList) - { - if (SecurityUtils.compareStrings(s.getKey().Trim(), claimKey.Trim())) - { - return true; - } - } - return false; - } - - private int countingPrivateClaims(Dictionary map, int counter) - { - List list = new List(map.Keys); - foreach (string s in list) - { - counter++; - object obj = map[s]; - if (obj.GetType() == typeof(Dictionary)) - { - counter = countingPrivateClaims((Dictionary)obj, counter); - } - } - return counter; - } - } + + + } + else + { + error.setError("JW011", String.Format("{0} wrong registered claim key", registeredClaimKey)); + return false; + } + } + } + return true; + } + private static bool isRevoqued(JwtSecurityToken jwtToken, JWTOptions options) + { + RevocationList rList = options.getRevocationList(); + return rList.isInRevocationList(jwtToken.Payload.Jti); + } + + private String getTokenPart(string token, String part) + { + JwtSecurityToken jwtToken = new JwtSecurityToken(token); + + switch (part) + { + case "payload": + return jwtToken.Payload.SerializeToJson(); + case "header": + return jwtToken.Header.SerializeToJson(); + case "id": + return jwtToken.Payload.Jti; + default: + error.setError("JW007", "Unknown token segment"); + return ""; + } + + } + + private bool verifyPrivateClaims(JwtSecurityToken jwtToken, PrivateClaims privateClaims, JWTOptions options) + { + RegisteredClaims registeredClaims = options.getAllRegisteredClaims(); + PublicClaims publicClaims = options.getAllPublicClaims(); + if (privateClaims == null || privateClaims.isEmpty()) + { + return true; + } + string jsonPayload = jwtToken.Payload.SerializeToJson(); + Dictionary map = null; + try + { + map = JsonConvert.DeserializeObject>(jsonPayload); + } + catch (Exception e) + { + this.error.setError("JW012", e.Message); + return false; + } + this.counter = 0; + bool validation = verifyNestedClaims(privateClaims.getNestedMap(), map, registeredClaims, publicClaims); + int pClaimsCount = countingPrivateClaims(privateClaims.getNestedMap(), 0); + if (validation && !(this.counter == pClaimsCount)) + { + return false; + } + return validation; + } + + private bool verifyNestedClaims(Dictionary pclaimMap, Dictionary map, + RegisteredClaims registeredClaims, PublicClaims publicClaims) + { + List mapClaimKeyList = new List(map.Keys); + List pClaimKeyList = new List(pclaimMap.Keys); + if (pClaimKeyList.Count > pClaimKeyList.Count) + { + return false; + } + foreach (String mapKey in mapClaimKeyList) + { + + if (!isRegistered(mapKey, registeredClaims) && !isPublic(mapKey, publicClaims)) + { + this.counter++; + if (!pclaimMap.ContainsKey(mapKey)) + { + return false; + } + + object op = pclaimMap[mapKey]; + object ot = map[mapKey]; + Type opt = op.GetType(); + Type ott = ot.GetType(); + Type int16 = Type.GetType("System.Int16", false, true); + Type int32 = Type.GetType("System.Int32", false, true); + Type int64 = Type.GetType("System.Int64", false, true); + if ((opt == typeof(string)) && (ott == typeof(string))) + { + + if (!SecurityUtils.compareStrings(((string)op).Trim(), ((string)ot).Trim())) + { + return false; + } + } + + else if (((opt == int16) || (opt == int32) || (opt == int64)) && ((ott == int16) || (ott == int32) || (ott == int64))) + { + if (Convert.ToInt32(op, System.Globalization.CultureInfo.InvariantCulture) != Convert.ToInt32(ot, System.Globalization.CultureInfo.InvariantCulture)) + { + return false; + } + } + else if (opt == typeof(bool)) + { + if (Convert.ToBoolean(op, System.Globalization.CultureInfo.InvariantCulture) != Convert.ToBoolean(ot, System.Globalization.CultureInfo.InvariantCulture)) + { + return false; + } + + } + else if ((op.GetType() == typeof(Dictionary)) && (ot.GetType() == typeof(JObject))) + { + + + bool flag = verifyNestedClaims((Dictionary)op, ((JObject)ot).ToObject>(), + registeredClaims, publicClaims); + if (!flag) + { + return false; + } + } + else + { + return false; + } + } + } + return true; + } + + private void AddHeaderParameters(JwtHeader header, JWTOptions options) + { + HeaderParameters parameters = options.GetHeaderParameters(); + List list = parameters.GetAll(); + Dictionary map = parameters.GetMap(); + foreach (string s in list) + { + header.Add(s.Trim(), ((string)map[s]).Trim()); + } + } + + private static bool VerifyHeader(JwtSecurityToken jwtToken, JWTOptions options) + { + int claimsNumber = jwtToken.Header.Count; + HeaderParameters parameters = options.GetHeaderParameters(); + if (parameters.IsEmpty() && claimsNumber == 2) + { + return true; + } + if (parameters.IsEmpty() && claimsNumber > 2) + { + return false; + } + + List allParms = parameters.GetAll(); + if (claimsNumber != allParms.Count + 2) + { + return false; + } + Dictionary map = parameters.GetMap(); + + + foreach (string s in allParms) + { + + if (!jwtToken.Header.ContainsKey(s.Trim())) + { + return false; + } + + + string claimValue = null; + try + { + claimValue = (string)jwtToken.Header[s.Trim()]; + } + catch (Exception) + { + return false; + } + String optionsValue = ((string)map[s]).Trim(); + if (!SecurityUtils.compareStrings(claimValue, optionsValue.Trim())) + { + return false; + } + } + return true; + + } + + private static bool isRegistered(string claimKey, RegisteredClaims registeredClaims) + { + + List registeredClaimsList = registeredClaims.getAllClaims(); + foreach (Claim s in registeredClaimsList) + { + if (SecurityUtils.compareStrings(s.getKey().Trim(), claimKey.Trim())) + { + return true; + } + } + return false; + } + + private static bool isPublic(string claimKey, PublicClaims publicClaims) + { + List publicClaimsList = publicClaims.getAllClaims(); + foreach (Claim s in publicClaimsList) + { + if (SecurityUtils.compareStrings(s.getKey().Trim(), claimKey.Trim())) + { + return true; + } + } + return false; + } + + private int countingPrivateClaims(Dictionary map, int counter) + { + List list = new List(map.Keys); + foreach (string s in list) + { + counter++; + object obj = map[s]; + if (obj.GetType() == typeof(Dictionary)) + { + counter = countingPrivateClaims((Dictionary)obj, counter); + } + } + return counter; + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/Claims.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/Claims.cs index c8b6542d9..fdd7bfda7 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/Claims.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/Claims.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Security; @@ -51,8 +52,8 @@ public virtual object getClaimValue(string key, Error _error) return _claims.ElementAt(i).getValue(); } } - _error.setError("CL001", "Could not find a claim with" + key + " key value"); - return ""; + _error.setError("CLA01", String.Format("Could not find a claim with {0} key value", key)); + return ""; } public bool isEmpty() diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaim.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaim.cs index 59481c1f6..45ed4455f 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaim.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaim.cs @@ -48,7 +48,7 @@ public static RegisteredClaim getRegisteredClaim(string registeredClaim, Error e if(error == null) return RegisteredClaim.NONE; if (registeredClaim == null) { - error.setError("RC002", "Unknown registered Claim"); + error.setError("RCL01", "Unknown registered Claim"); return RegisteredClaim.NONE; } switch (registeredClaim.Trim()) @@ -68,7 +68,7 @@ public static RegisteredClaim getRegisteredClaim(string registeredClaim, Error e case "jti": return RegisteredClaim.jti; default: - error.setError("RC002", "Unknown registered Claim"); + error.setError("RCL02", "Unknown registered Claim"); return RegisteredClaim.NONE; } } @@ -117,7 +117,7 @@ public static bool validateClaim(string registeredClaimKey, string registeredCla if(token == null) { - error.setError("RC000", "Token parameter is null"); + error.setError("RCL13", "Token parameter is null"); return false; } Int32 newTime = 0; @@ -172,7 +172,7 @@ public static bool validateClaim(string registeredClaimKey, string registeredCla case RegisteredClaim.jti: return SecurityUtils.compareStrings(token.Payload.Jti, registeredClaimValue); default: - error.setError("RC003", "Unknown registered Claim"); + error.setError("RCL03", "Unknown registered Claim"); return false; } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaims.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaims.cs index f65f05c01..f3df80060 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaims.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/JWTClaims/RegisteredClaims.cs @@ -29,7 +29,7 @@ public bool setClaim(string key, string value, Error error) } else { - error.setError("RC001", "Wrong registered key value"); + error.setError("RCS02", "Wrong registered key value"); return false; } } @@ -47,14 +47,14 @@ public bool setTimeValidatingClaim(string key, string value, string customValida } catch (Exception) { - error.setError("RC004", "Incorrect date format. Expected yyyy/MM/dd HH:mm:ss"); + error.setError("RCS04", "Date format error; expected yyyy/MM/dd HH:mm:ss"); return false; } return setClaim(key, date.ToString(CultureInfo.InvariantCulture), error); } else { - error.setError("RC001", "Wrong registered key value"); + error.setError("RCS02", "Wrong registered key value"); return false; } } @@ -101,7 +101,7 @@ public override object getClaimValue(string key, Error error) return _claims[i].getValue(); } } - error.setError("RC001", "Could not find a claim with" + key + " key value"); + error.setError("RCS03", String.Format("Could not find a claim with {0} key value", key)); return ""; } else diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/JWTAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/JWTAlgorithm.cs index 894827e74..55b96c2e0 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/JWTAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/JWTAlgorithm.cs @@ -37,7 +37,7 @@ public static string valueOf(JWTAlgorithm jWTAlgorithm, Error error) return "ES512"; default: - error.setError("JA001", "Unrecognized algorithm"); + error.setError("JWA01", "Unrecognized algorithm"); return "Unrecognized algorithm"; } } @@ -47,7 +47,7 @@ public static JWTAlgorithm getJWTAlgorithm(string jWTAlgorithm, Error error) if(error == null) return JWTAlgorithm.NONE; if (jWTAlgorithm == null) { - error.setError("JA002", "Unrecognized algorithm"); + error.setError("JWA02", "Unrecognized algorithm"); return JWTAlgorithm.NONE; } switch (jWTAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) @@ -68,7 +68,7 @@ public static JWTAlgorithm getJWTAlgorithm(string jWTAlgorithm, Error error) return JWTAlgorithm.ES512; default: - error.setError("JA002", "Unrecognized algorithm"); + error.setError("JWA02", "Unrecognized algorithm"); return JWTAlgorithm.NONE; } } @@ -95,7 +95,7 @@ public static JWTAlgorithm getJWTAlgorithm_forVerification(string jWTAlgorithm, case SecurityAlgorithms.EcdsaSha512: return JWTAlgorithm.ES512; default: - error.setError("JA004", "Unrecognized algorithm"); + error.setError("JWA05", "Unrecognized algorithm"); return JWTAlgorithm.NONE; } } @@ -137,7 +137,7 @@ internal static SigningCredentials getSigningCredentials(JWTAlgorithm jWTAlgorit return new SigningCredentials(key, SecurityAlgorithms.EcdsaSha512); default: - error.setError("JA003", "Unknown algorithm"); + error.setError("JWA06", "Unrecognized algorithm"); return null; } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/RevocationList.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/RevocationList.cs index 5110d8138..707d17ef7 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/RevocationList.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/Utils/RevocationList.cs @@ -4,6 +4,7 @@ using System.Security; using SecurityAPICommons.Utils; using SecurityAPICommons.Commons; +using System; namespace GeneXusJWT.GenexusJWTUtils { @@ -30,7 +31,7 @@ public bool deleteFromRevocationList(string id) return true; } } - this.error.setError("OP001", "The " + id + " id is not in the revocation list"); + this.error.setError("REL01", String.Format("The id {0} is not in the revocation list", id)); return false; } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusSftp/Sftp/SftpClient.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusSftp/Sftp/SftpClient.cs index bb51d04c4..aa7a53a92 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusSftp/Sftp/SftpClient.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusSftp/Sftp/SftpClient.cs @@ -51,27 +51,19 @@ public override bool Connect(SftpOptions options) return false; } bool useKey = false; - if (SecurityUtils.compareStrings("", options.KeyPath) || SecurityUtils.compareStrings("", options.User) || SecurityUtils.compareStrings("", options.KeyPassword)) - { - useKey = false; - if (SecurityUtils.compareStrings("", options.User) - || SecurityUtils.compareStrings("", options.Password)) - { - - this.error.setError("SF001", "Authentication misconfiguration"); - return false; - } - else - { - useKey = false; - } - } - else - { - useKey = true; - } - - + if (!SecurityUtils.compareStrings("", options.KeyPath) ) + { + useKey = true; + }else + { + if (SecurityUtils.compareStrings("", options.User) + || SecurityUtils.compareStrings("", options.Password)) + { + + this.error.setError("SF001", "Authentication misconfiguration. Missing user or password"); + return false; + } + } if (SecurityUtils.compareStrings("", options.Host)) { @@ -318,9 +310,6 @@ private void SetupChannelSftp(SftpOptions options, bool useKey) PrivateKeyFile keyFile = new PrivateKeyFile(options.KeyPath, options.KeyPassword); method.Add(new PrivateKeyAuthenticationMethod(options.User, keyFile)); - - - } else { diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/DSig/XmlDSigSigner.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/DSig/XmlDSigSigner.cs index 865c91d21..0317a6048 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/DSig/XmlDSigSigner.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/DSig/XmlDSigSigner.cs @@ -12,703 +12,480 @@ namespace GeneXusXmlSignature.GeneXusDSig { - [SecuritySafeCritical] - public class XmlDSigSigner : SecurityAPIObject, IXmlDSigSignerObject - { - - private AsymmetricAlgorithm privateKey; - private AsymmetricAlgorithm publicKey; - private string digest; - private string asymAlgorithm; - - public XmlDSigSigner() : base() - { + [SecuritySafeCritical] + public class XmlDSigSigner : SecurityAPIObject, IXmlDSigSignerObject + { + + private AsymmetricAlgorithm privateKey; + private AsymmetricAlgorithm publicKey; + private string digest; + private string asymAlgorithm; + + public XmlDSigSigner() : base() + { + + } + + /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + [SecuritySafeCritical] + public bool DoSignFile(String xmlFilePath, PrivateKeyManager key, + CertificateX509 certificate, String outputPath, DSigOptions options) + { + return Convert.ToBoolean(AxuiliarSign(xmlFilePath, key, certificate, outputPath, options, true, "")); + } + + [SecuritySafeCritical] + public String DoSign(String xmlInput, PrivateKeyManager key, + CertificateX509 certificate, DSigOptions options) + { + return AxuiliarSign(xmlInput, key, certificate, "", options, false, ""); + } + + [SecuritySafeCritical] + public bool DoSignFileElement(String xmlFilePath, String xPath, + PrivateKeyManager key, CertificateX509 certificate, String outputPath, + DSigOptions options) + { + return Convert.ToBoolean(AxuiliarSign(xmlFilePath, key, certificate, outputPath, options, true, xPath)); + } + + [SecuritySafeCritical] + public String DoSignElement(String xmlInput, String xPath, PrivateKeyManager key, + CertificateX509 certificate, DSigOptions options) + { + return AxuiliarSign(xmlInput, key, certificate, "", options, false, xPath); + } + + [SecuritySafeCritical] + public bool DoVerify(string xmlSigned, DSigOptions options) + { + return AuxiliarVerify(xmlSigned, options, null, false, false); + } + + [SecuritySafeCritical] + public bool DoVerifyFile(string xmlFilePath, DSigOptions options) + { + return AuxiliarVerify(xmlFilePath, options, null, true, false); + } + + [SecuritySafeCritical] + public bool DoVerifyWithCert(string xmlSigned, CertificateX509 certificate, DSigOptions options) + { + return AuxiliarVerify(xmlSigned, options, certificate, false, true); + } + + [SecuritySafeCritical] + public bool DoVerifyFileWithCert(string xmlFilePath, CertificateX509 certificate, DSigOptions options) + { + return AuxiliarVerify(xmlFilePath, options, certificate, true, true); + } + + + /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + private string AxuiliarSign(string xmlInput, PrivateKey key, + Certificate certificate, string outputPath, DSigOptions options, bool isFile, string xPath) + { + if (TransformsWrapperUtils.getTransformsWrapper(options.DSigSignatureType, + this.error) != TransformsWrapper.ENVELOPED) + { + error.setError("XD001", "Not implemented DSigType"); + } + CertificateX509 cert = (CertificateX509)certificate; + if (!cert.Inicialized) + { + this.error.setError("XD002", "Certificate not loaded"); + } + else if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "ECDSA")) + { + this.error.setError("XD014", "XML signature with ECDSA keys is not implemented on Net Framework"); + return ""; + } - } + XmlDocument xmlDoc = LoadDocument(isFile, xmlInput, options); + if (this.HasError()) + { + return ""; + } + string result = Sign(xmlDoc, (PrivateKeyManager)key, cert, options.DSigSignatureType, + options.Canonicalization, options.KeyInfoType, xPath, options.IdentifierAttribute); + if (isFile) + { + // string prefix = "".Trim(); + string prefix = ""; + return SignatureUtils.writeToFile(result, outputPath, prefix, this.error).ToString(); + } - /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + return result; + } - public bool DoSignFile(string xmlFilePath, PrivateKeyManager key, CertificateX509 certificate, string outputPath, DSigOptions options) - { - this.error.cleanError(); - if(certificate == null) + private bool AuxiliarVerify(string xmlInput, DSigOptions options, CertificateX509 certificate, bool isFile, bool withCert) + { + if (TransformsWrapperUtils.getTransformsWrapper(options.DSigSignatureType, + this.error) != TransformsWrapper.ENVELOPED) { - this.error.setError("DS000", "Certificate parameter is null"); - return false; + error.setError("XD001", "Not implemented DSigType"); } - if(options == null) + XmlDocument xmlDoc = LoadDocument(isFile, xmlInput, options); + if (this.HasError()) { - this.error.setError("DS000", "Options parameter is null"); return false; } - return doSignFilePKCS12(xmlFilePath, key, certificate, options.DSigSignatureType, options.Canonicalization, outputPath, options.KeyInfoType, options.XmlSchemaPath); - } + if (withCert) + { + CertificateX509 cert = (CertificateX509)certificate; + if (!cert.Inicialized) + { + this.error.setError("XD002", "Certificate not loaded"); + } + else if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "ECDSA")) + { + this.error.setError("XD014", "XML signature with ECDSA keys is not implemented on Net Framework"); + return false; + } + return Verify(xmlDoc, withCert, certificate, options); + } + else + { + return Verify(xmlDoc, withCert, null, options); + } + } - public bool DoSignFileElement(string xmlFilePath, string xPath, PrivateKeyManager key, CertificateX509 certificate, string outputPath, DSigOptions options) - { - this.error.cleanError(); - if (certificate == null) + private string Sign(XmlDocument xmlInput, PrivateKeyManager key, CertificateX509 certificate, + string dSigType, string canonicalizationType, string keyInfoType, string xpath, string id) + { + bool flag = inicializeInstanceVariables(key, certificate); + if (!flag) { - this.error.setError("DS000", "Certificate parameter is null"); - return false; + return ""; + } + + SignatureElementType signatureElementType; + if (!SecurityUtils.compareStrings(xpath, "")) + { + if (xpath[0] == '#') + { + signatureElementType = SignatureElementType.id; + if (id == null || SecurityUtils.compareStrings(id, "")) + { + this.error.setError("XD003", "Identifier attribute name missing"); + return ""; + } + } + else + { + signatureElementType = SignatureElementType.path; + } } - if (options == null) + else { - this.error.setError("DS000", "Options parameter is null"); - return false; + signatureElementType = SignatureElementType.document; } - return doSignFileElementPKCS12(xmlFilePath, xPath, key, certificate, options.DSigSignatureType, options.Canonicalization, outputPath, options.KeyInfoType, options.XmlSchemaPath, options.IdentifierAttribute); - } - public string DoSign(string xmlInput, PrivateKeyManager key, CertificateX509 certificate, DSigOptions options) - { - this.error.cleanError(); - if (certificate == null) + /***WHITESPACES***/ + xmlInput.PreserveWhitespace = true; + CanonicalizerWrapper canon = CanonicalizerWrapperUtils.getCanonicalizerWrapper(canonicalizationType, this.error); + + + CanonicalizerWrapper canonW = CanonicalizerWrapperUtils.getCanonicalizerWrapper(canonicalizationType, this.error); + if (this.HasError()) { - this.error.setError("DS000", "Certificate parameter is null"); return ""; } - if (options == null) + + Reference reference = new Reference(); + + XmlNode parentNode; + SignedXml signedXml; + switch (signatureElementType) + { + case SignatureElementType.path: + XmlNode pathNode = SignatureUtils.getNodeFromPath(xmlInput, xpath, this.error); + XmlElement pathElement = pathNode as XmlElement; + if (this.HasError() || pathElement == null) + { + return ""; + } + parentNode = pathNode.ParentNode; + + + + signedXml = new SignedXml(pathElement); + XmlDsigXPathTransform XPathTransform = CreateXPathTransform(xpath); + reference.Uri = pathNode.NamespaceURI; + reference.AddTransform(XPathTransform); + break; + case SignatureElementType.id: + XmlNode idNode = SignatureUtils.getNodeFromID(xmlInput, id, xpath, this.error); + XmlElement idElement = idNode as XmlElement; + + if (this.HasError() || idElement == null) + { + return ""; + } + + reference.Uri = xpath; + signedXml = new SignedXml(idElement); + parentNode = idNode.ParentNode; + break; + default: + signedXml = new SignedXml(xmlInput); + parentNode = xmlInput.DocumentElement; + reference.Uri = ""; + break; + } + + signedXml.SigningKey = this.privateKey; + signedXml.SignedInfo.CanonicalizationMethod = CanonicalizerWrapperUtils.getCanonicalizationMethodAlorithm(canonW, this.error); + if (this.HasError()) { - this.error.setError("DS000", "Options parameter is null"); return ""; } - return doSignPKCS12(xmlInput, key, certificate, options.DSigSignatureType, options.Canonicalization, options.KeyInfoType, options.XmlSchemaPath); - } - public string DoSignElement(string xmlInput, string xPath, PrivateKeyManager key, CertificateX509 certificate, DSigOptions options) - { - this.error.cleanError(); - if (certificate == null) + XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); + reference.AddTransform(env); + + addCanonTransform(reference, canonW); + + signedXml.AddReference(reference); + + KeyInfo keyInfo = createKeyInfo(certificate, keyInfoType); + + if (keyInfo != null) { - this.error.setError("DS000", "Certificate parameter is null"); + signedXml.KeyInfo = keyInfo; + } + try + { + signedXml.ComputeSignature(); + } + catch (Exception e) + { + this.error.setError("XD004", e.Message); return ""; } - if (options == null) + XmlElement xmlDigitalSignature = null; + try + { + xmlDigitalSignature = signedXml.GetXml(); + } + catch (Exception ex) { - this.error.setError("DS000", "Options parameter is null"); + this.error.setError("XD005", ex.Message); return ""; } - return doSignElementPKCS12(xmlInput, xPath, key, certificate, options.DSigSignatureType, options.Canonicalization, options.KeyInfoType, options.XmlSchemaPath, options.IdentifierAttribute); - } - public bool DoVerify(string xmlSigned, DSigOptions options) - { - this.error.cleanError(); - if (options == null) + + + + parentNode.AppendChild(xmlDigitalSignature); + // xmlInput.DocumentElement.AppendChild(xmlInput.ImportNode(xmlDigitalSignature, true)); + + + return SignatureUtils.XMLDocumentToString(xmlInput); + + } + + private bool Verify(XmlDocument doc, bool withCert, CertificateX509 certificate, DSigOptions options) + { + doc.PreserveWhitespace = true; + XmlNodeList nodeList = null; + SignedXml signedXML = null; + XmlNode node = null; + //searching for an element + try + { + nodeList = doc.GetElementsByTagName("XPath"); + } + catch (Exception) + { + //NOOP + } + if (nodeList == null || nodeList.Count == 0) + { + //search for id + + string idValue = SignatureUtils.getIDNodeValue(doc); + if (idValue != null) + { + node = SignatureUtils.getNodeFromID(doc, options.IdentifierAttribute, idValue, this.error); + } + else + { + //all document + node = doc.DocumentElement; + + } + + } + else { - this.error.setError("DS000", "Options parameter is null"); - return false; + //search for xpath + //java xmlsec hack + if (nodeList == null || nodeList.Count == 0) + { + nodeList = doc.GetElementsByTagName("ds:XPath"); + } + + XmlNode nodee = nodeList[0]; + string path = nodee.InnerText; + node = SignatureUtils.getNodeFromPath(doc, path, this.error); + if (this.HasError()) + { + return false; + } } - XmlDocument xmlDoc = SignatureUtils.documentFromString(xmlSigned, options.XmlSchemaPath, this.error); - if (this.HasError()) - { - return false; - } - return verify(xmlDoc, options.IdentifierAttribute); - } + + XmlElement element = node as XmlElement; + signedXML = new SignedXml(element); + - public bool DoVerifyFile(string xmlFilePath, DSigOptions options) - { - this.error.cleanError(); - if(options == null) + + XmlNodeList signatureNodes = doc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl); + //java xmlsec hack + if (signatureNodes == null || signatureNodes.Count == 0) { - this.error.setError("DS000", "Options parameter is null"); - return false; + signatureNodes = doc.GetElementsByTagName("ds:Signature"); } - if (!SignatureUtils.validateExtensionXML(xmlFilePath)) - { - this.error.setError("DS001", "The file is not an xml file"); - return false; - } - XmlDocument xmlDoc = SignatureUtils.documentFromFile(xmlFilePath, options.XmlSchemaPath, this.error); - if (this.HasError()) - { - return false; - } - return verify(xmlDoc, options.IdentifierAttribute); - } - - public bool DoVerifyWithCert(string xmlSigned, CertificateX509 certificate, DSigOptions options) - { - this.error.cleanError(); - if(certificate == null) - { - this.error.setError("DS003", "Certificate not loaded"); - return false; + bool res = false; + try + { + signedXML.LoadXml((XmlElement)signatureNodes[0]); + if (withCert) + { + res = signedXML.CheckSignature(certificate.Cert, true); + } + else + { + res = signedXML.CheckSignature(); + } } - if(options == null) + catch (Exception e) { - this.error.setError("DS003", "Options is null"); + this.error.setError("XD006", e.Message); return false; } - if (!certificate.Inicialized) - { - this.error.setError("DS003", "Certificate not loaded"); - return false; - } - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "ECDSA")) - { - this.error.setError("DS004", "XML signature with ECDSA keys is not implemented on Net Framework"); - return false; - } - XmlDocument xmlDoc = SignatureUtils.documentFromString(xmlSigned, options.XmlSchemaPath, this.error); - if (this.HasError()) - { - return false; - } - return verify(xmlDoc, certificate); - } - - public bool DoVerifyFileWithCert(string xmlFilePath, CertificateX509 certificate, DSigOptions options) - { - this.error.cleanError(); - if(certificate == null) - { - this.error.setError("DS005", "Certificate not loaded"); - return false; + + return res; + } + + private KeyInfo createKeyInfo(CertificateX509 certificate, string keyInfoType) + { + KeyInfo keyInfo = new KeyInfo(); + KeyInfoType kinfo = KeyInfoTypeUtils.getKeyInfoType(keyInfoType, this.error); + switch (kinfo) + { + case KeyInfoType.KeyValue: + + if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "RSA")) + { + keyInfo.AddClause(new RSAKeyValue((RSA)certificate.getPublicKeyXML())); + } + else + { + keyInfo.AddClause(new DSAKeyValue((DSA)certificate.getPublicKeyXML())); + } + break; + case KeyInfoType.X509Certificate: + + KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(); + keyInfoX509Data.AddCertificate((X509Certificate)certificate.Cert); + keyInfoX509Data.AddSubjectName(certificate.Cert.SubjectName.Name); + keyInfoX509Data.AddIssuerSerial(certificate.Cert.IssuerName.Name, certificate.Cert.SerialNumber); + keyInfo.AddClause((KeyInfoClause)keyInfoX509Data); + + break; + case KeyInfoType.NONE: + keyInfo = null; + break; } - if(options == null) + return keyInfo; + } + + + private static void addCanonTransform(Reference reference, CanonicalizerWrapper canonW) + { + + switch (canonW) { - this.error.setError("DS005", "Options is null"); - return false; + case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: + reference.AddTransform(new XmlDsigC14NTransform()); + break; + case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: + reference.AddTransform(new XmlDsigC14NWithCommentsTransform()); + break; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: + reference.AddTransform(new XmlDsigExcC14NTransform()); + break; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: + reference.AddTransform(new XmlDsigExcC14NWithCommentsTransform()); + break; } - if (!certificate.Inicialized) - { - this.error.setError("DS005", "Certificate not loaded"); - } - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "ECDSA")) - { - this.error.setError("DS006", "XML signature with ECDSA keys is not implemented on Net Framework"); - return false; - } - if (!SignatureUtils.validateExtensionXML(xmlFilePath)) - { - this.error.setError("DS007", "The file is not an xml file"); - return false; - } - XmlDocument xmlDoc = SignatureUtils.documentFromFile(xmlFilePath, options.XmlSchemaPath, this.error); - return verify(xmlDoc, certificate); - - } - - - /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ - - private bool doSignFilePKCS12(string xmlFilePath, PrivateKeyManager key, CertificateX509 certificate, string dSigType, string canonicalizationType, string outputPath, string keyInfoType, string xmlSchemaPath) - { - if (TransformsWrapperUtils.getTransformsWrapper(dSigType, this.error) != TransformsWrapper.ENVELOPED) - { - error.setError("DS009", "Not implemented DSigType"); - return false; - } - if (!SignatureUtils.validateExtensionXML(xmlFilePath)) - { - this.error.setError("DS010", "Not XML file"); - return false; - } - if (!certificate.Inicialized) - { - this.error.setError("DS011", "Certificate not loaded"); - return false; - } - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "ECDSA")) - { - this.error.setError("DS004", "XML signature with ECDSA keys is not implemented on Net Framework"); - return false; - } - - XmlDocument xmlDoc = SignatureUtils.documentFromFile(xmlFilePath, xmlSchemaPath, this.error); - if (this.HasError()) - { - return false; - } - string result = Sign(xmlDoc, key, certificate, dSigType, canonicalizationType, keyInfoType, "", ""); - if (result == null || SecurityUtils.compareStrings("", result)) - { - this.error.setError("DS012", "Error generating signature"); - return false; - } - else - { - // string prefix = "".Trim(); - string prefix = ""; - return SignatureUtils.writeToFile(result, outputPath, prefix, this.error); - } - } - - private bool doSignFileElementPKCS12(string xmlFilePath, string xPath, PrivateKeyManager key, CertificateX509 certificate, string dSigType, string canonicalizationType, string outputPath, string keyInfoType, string xmlSchemaPath, string id) - { - if (TransformsWrapperUtils.getTransformsWrapper(dSigType, this.error) != TransformsWrapper.ENVELOPED) - { - error.setError("DS013", "Not implemented DSigType"); - return false; - } - if (!SignatureUtils.validateExtensionXML(xmlFilePath)) - { - this.error.setError("DS014", "Not XML file"); - return false; - } - if (!certificate.Inicialized) - { - this.error.setError("DS015", "Certificate not loaded"); - } - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "ECDSA")) - { - this.error.setError("DS004", "XML signature with ECDSA keys is not implemented on Net Framework"); - return false; - } - XmlDocument xmlDoc = SignatureUtils.documentFromFile(xmlFilePath, xmlSchemaPath, this.error); - if (this.HasError()) - { - return false; - } - string result = Sign(xmlDoc, key, certificate, dSigType, canonicalizationType, keyInfoType, xPath, id); - if (result == null || SecurityUtils.compareStrings("", result)) - { - this.error.setError("DS016", "Error generating signature"); - return false; - } - else - { - // string prefix = ""; - string prefix = ""; - return SignatureUtils.writeToFile(result, outputPath, prefix, this.error); - } - } - - private string doSignElementPKCS12(string xmlInput, string xPath, PrivateKeyManager key, CertificateX509 certificate, string dSigType, string canonicalizationType, string keyInfoType, string xmlSchemaPath, string id) - { - if (TransformsWrapperUtils.getTransformsWrapper(dSigType, this.error) != TransformsWrapper.ENVELOPED) - { - error.setError("DS017", "Not implemented DSigType"); - return ""; - } - if (!certificate.Inicialized) - { - this.error.setError("DS018", "Certificate not loaded"); - return ""; - } - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "ECDSA")) - { - this.error.setError("DS004", "XML signature with ECDSA keys is not implemented on Net Framework"); - return ""; - } - XmlDocument xmlDoc = SignatureUtils.documentFromString(xmlInput, xmlSchemaPath, this.error); - if (this.HasError()) - { - return ""; - } - return Sign(xmlDoc, key, certificate, dSigType, canonicalizationType, keyInfoType, xPath, id); - } - - private string doSignPKCS12(string xmlInput, PrivateKeyManager key, CertificateX509 certificate, string dSigType, string canonicalizationType, string keyInfoType, string xmlSchemaPath) - { - if (TransformsWrapperUtils.getTransformsWrapper(dSigType, this.error) != TransformsWrapper.ENVELOPED) - { - error.setError("DS019", "Not implemented DSigType"); - return ""; - } - if (!certificate.Inicialized) - { - this.error.setError("DS0220", "Certificate not loaded"); - return ""; - } - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "ECDSA")) - { - this.error.setError("DS004", "XML signature with ECDSA keys is not implemented on Net Framework"); - return ""; - } - XmlDocument xmlDoc = SignatureUtils.documentFromString(xmlInput, xmlSchemaPath, this.error); - if (this.HasError()) - { - return ""; - } - return Sign(xmlDoc, key, certificate, dSigType, canonicalizationType, keyInfoType, "", ""); - } - - private string Sign(XmlDocument xmlInput, PrivateKeyManager key, CertificateX509 certificate, - string dSigType, string canonicalizationType, string keyInfoType, string xpath, string id) - { - if(!SecurityUtils.compareStrings(dSigType, "ENVELOPED")) - { - this.error.setError("DS040", "Not implemented DSigType"); - return ""; + } + + + private bool inicializeInstanceVariables(PrivateKeyManager key, CertificateX509 certificate) + { + + this.privateKey = key.getPrivateKeyForXML(); + if (this.privateKey == null) + { + this.error = key.GetError(); + return false; + } - bool flag = inicializeInstanceVariables(key, certificate); - if (!flag) - { - return ""; - } - - SignatureElementType signatureElementType; - if (!SecurityUtils.compareStrings(xpath, "")) - { - if (xpath[0] == '#') - { - signatureElementType = SignatureElementType.id; - if (id == null || SecurityUtils.compareStrings(id, "")) - { - this.error.setError("DS021", "identifier attribute name missing"); - return ""; - } - } - else - { - signatureElementType = SignatureElementType.path; - } - } - else - { - signatureElementType = SignatureElementType.document; - } - - /***WHITESPACES***/ - xmlInput.PreserveWhitespace = true; - CanonicalizerWrapper canon = CanonicalizerWrapperUtils.getCanonicalizerWrapper(canonicalizationType, this.error); - - - CanonicalizerWrapper canonW = CanonicalizerWrapperUtils.getCanonicalizerWrapper(canonicalizationType, this.error); - if (this.HasError()) - { - return ""; - } - - Reference reference = new Reference(); - - XmlNode parentNode; - SignedXml signedXml; - switch (signatureElementType) - { - case SignatureElementType.path: - XmlNode pathNode = SignatureUtils.getNodeFromPath(xmlInput, xpath, this.error); - XmlElement pathElement = pathNode as XmlElement; - if (this.HasError() || pathElement == null) - { - return ""; - } - parentNode = pathNode.ParentNode; - - - - signedXml = new SignedXml(pathElement); - XmlDsigXPathTransform XPathTransform = CreateXPathTransform(xpath); - reference.Uri = pathNode.NamespaceURI; - reference.AddTransform(XPathTransform); - break; - case SignatureElementType.id: - XmlNode idNode = SignatureUtils.getNodeFromID(xmlInput, id, xpath, this.error); - XmlElement idElement = idNode as XmlElement; - - if (this.HasError() || idElement == null) - { - return ""; - } - - reference.Uri = xpath; - signedXml = new SignedXml(idElement); - parentNode = idNode.ParentNode; - break; - default: - signedXml = new SignedXml(xmlInput); - parentNode = xmlInput.DocumentElement; - reference.Uri = ""; - break; - } - - signedXml.SigningKey = this.privateKey; - signedXml.SignedInfo.CanonicalizationMethod = CanonicalizerWrapperUtils.getCanonicalizationMethodAlorithm(canonW, this.error); - if (this.HasError()) - { - return ""; - } - - XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); - reference.AddTransform(env); - - addCanonTransform(reference, canonW); - - signedXml.AddReference(reference); - - KeyInfo keyInfo = createKeyInfo(certificate, keyInfoType); - - if (keyInfo != null) - { - signedXml.KeyInfo = keyInfo; - } - try - { - signedXml.ComputeSignature(); - } - catch (Exception) - { - this.error.setError("DS023", "Error on signing"); - return ""; - } - XmlElement xmlDigitalSignature = null; - try - { - xmlDigitalSignature = signedXml.GetXml(); - } - catch (Exception) - { - this.error.setError("DS028", "Error at signing"); - return ""; - } - - - - - parentNode.AppendChild(xmlDigitalSignature); - // xmlInput.DocumentElement.AppendChild(xmlInput.ImportNode(xmlDigitalSignature, true)); - - - return SignatureUtils.XMLDocumentToString(xmlInput); - - } - - private bool verify(XmlDocument doc, string id) - { - doc.PreserveWhitespace = true; - XmlNodeList nodeList = null; - try - { - nodeList = doc.GetElementsByTagName("XPath"); - } - catch (Exception) - { - //NOOP - } - if (nodeList == null || nodeList.Count == 0) - { - - return verifyDocument(doc, id); - - } - else - { - return verifyPath(doc); - } - } - - private bool verifyPath(XmlDocument doc) - { - - doc.PreserveWhitespace = true; - - XmlNodeList nodeList = doc.GetElementsByTagName("XPath"); - //java xmlsec hack - if (nodeList == null || nodeList.Count == 0) - { - nodeList = doc.GetElementsByTagName("ds:XPath"); - } - - XmlNode node = nodeList[0]; - string path = node.InnerText; - XmlNode signedNode = SignatureUtils.getNodeFromPath(doc, path, this.error); - if (this.HasError()) - { - return false; - } - XmlElement pathElement = signedNode as XmlElement; - SignedXml signedXML = new SignedXml(pathElement); - XmlNodeList signatureNodes = doc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl); - //java xmlsec hack - if (signatureNodes == null || signatureNodes.Count == 0) - { - signatureNodes = doc.GetElementsByTagName("ds:Signature"); - } - bool res = false; - try - { - signedXML.LoadXml((XmlElement)signatureNodes[0]); - res = signedXML.CheckSignature(); - } - catch (Exception) - { - this.error.setError("DS036", "Error on signature verification"); - return false; - } - - return res; - - - - } - - private bool verifyID(XmlDocument doc, string identifier, string idValue) - { - XmlNode node = SignatureUtils.getNodeFromID(doc, identifier, idValue, this.error); - XmlElement element = node as XmlElement; - SignedXml signedXML = new SignedXml(element); - XmlNodeList signatureNodes = doc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl); - //java xmlsec hack - if (signatureNodes == null || signatureNodes.Count == 0) - { - signatureNodes = doc.GetElementsByTagName("ds:Signature"); - } - bool res = false; - try - { - signedXML.LoadXml((XmlElement)signatureNodes[0]); - res = signedXML.CheckSignature(); - } - catch (Exception) - { - this.error.setError("DS037", "Error on signature verification"); - return false; - } - - return res; - - } - - - private bool verifyDocument(XmlDocument doc, string id) - { - /***WHITESPACES***/ - doc.PreserveWhitespace = true; - string idValue = SignatureUtils.getIDNodeValue(doc); - if (!SecurityUtils.compareStrings("", idValue) && idValue[0] == '#') - { - if (id == null || SecurityUtils.compareStrings("", id)) - { - this.error.setError("DS038", "The signature has a Reference URI by ID and ID attribute name is not defined"); - return false; - } - return verifyID(doc, id, idValue); - } - SignedXml signedXML = new SignedXml(doc); - XmlNodeList nodeList = doc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl); - //java xmlsec hack - if (nodeList == null || nodeList.Count == 0) - { - nodeList = doc.GetElementsByTagName("ds:Signature"); - } - bool res = false; - try - { - signedXML.LoadXml((XmlElement)nodeList[0]); - res = signedXML.CheckSignature(); - } - catch (Exception) - { - this.error.setError("DS039", "Error on signature verification"); - - return false; - } - return res; - - - - - } - - private bool verify(XmlDocument doc, CertificateX509 certificate) - { - /***WHITESPACES***/ - doc.PreserveWhitespace = true; - - SignedXml signedXml = new SignedXml(doc); - XmlNodeList nodeList = doc.GetElementsByTagName("Signature"); - signedXml.LoadXml((XmlElement)nodeList[0]); - return signedXml.CheckSignature(certificate.Cert, true); - } - - private KeyInfo createKeyInfo(CertificateX509 certificate, string keyInfoType) - { - KeyInfo keyInfo = new KeyInfo(); - KeyInfoType kinfo = KeyInfoTypeUtils.getKeyInfoType(keyInfoType, this.error); - switch (kinfo) - { - case KeyInfoType.KeyValue: - - if (SecurityUtils.compareStrings(certificate.getPublicKeyAlgorithm(), "RSA")) - { - keyInfo.AddClause(new RSAKeyValue((RSA)certificate.getPublicKeyXML())); - } - else - { - keyInfo.AddClause(new DSAKeyValue((DSA)certificate.getPublicKeyXML())); - } - break; - case KeyInfoType.X509Certificate: - - KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(); - keyInfoX509Data.AddCertificate((X509Certificate)certificate.Cert); - keyInfoX509Data.AddSubjectName(certificate.Cert.SubjectName.Name); - keyInfoX509Data.AddIssuerSerial(certificate.Cert.IssuerName.Name, certificate.Cert.SerialNumber); - keyInfo.AddClause((KeyInfoClause)keyInfoX509Data); - - break; - case KeyInfoType.NONE: - keyInfo = null; - break; - } - return keyInfo; - } - - - private static void addCanonTransform(Reference reference, CanonicalizerWrapper canonW) - { - - switch (canonW) - { - case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: - reference.AddTransform(new XmlDsigC14NTransform()); - break; - case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: - reference.AddTransform(new XmlDsigC14NWithCommentsTransform()); - break; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: - reference.AddTransform(new XmlDsigExcC14NTransform()); - break; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: - reference.AddTransform(new XmlDsigExcC14NWithCommentsTransform()); - break; - } - } - - - private bool inicializeInstanceVariables(PrivateKeyManager key, CertificateX509 certificate) - { - - this.privateKey = key.getPrivateKeyForXML(); - if (this.privateKey == null) - { - this.error = key.GetError(); - return false; - - } - this.publicKey = certificate.getPublicKeyXML(); - this.digest = certificate.getPublicKeyHash(); - this.asymAlgorithm = certificate.getPublicKeyAlgorithm(); - return true; - } - - // Create the XML that represents the transform. - private static XmlDsigXPathTransform CreateXPathTransform(string XPathString) - { - // Create a new XMLDocument object. - XmlDocument doc = new XmlDocument() { XmlResolver = null }; + this.publicKey = certificate.getPublicKeyXML(); + this.digest = certificate.getPublicKeyHash(); + this.asymAlgorithm = certificate.getPublicKeyAlgorithm(); + return true; + } + + // Create the XML that represents the transform. + private static XmlDsigXPathTransform CreateXPathTransform(string XPathString) + { + // Create a new XMLDocument object. + XmlDocument doc = new XmlDocument() { XmlResolver = null }; // Create a new XmlElement. XmlElement xPathElem = doc.CreateElement("XPath"); - // Set the element text to the value - // of the XPath string. - xPathElem.InnerText = XPathString; + // Set the element text to the value + // of the XPath string. + xPathElem.InnerText = XPathString; + + // Create a new XmlDsigXPathTransform object. + XmlDsigXPathTransform xForm = new XmlDsigXPathTransform(); + + // Load the XPath XML from the element. + xForm.LoadInnerXml(xPathElem.SelectNodes(".")); + + // Return the XML that represents the transform. + return xForm; + } - // Create a new XmlDsigXPathTransform object. - XmlDsigXPathTransform xForm = new XmlDsigXPathTransform(); - // Load the XPath XML from the element. - xForm.LoadInnerXml(xPathElem.SelectNodes(".")); - // Return the XML that represents the transform. - return xForm; - } + private XmlDocument LoadDocument(bool isFile, String path, DSigOptions options) + { + XmlDocument xmlDoc = null; + if (isFile) + { + if (!SignatureUtils.validateExtensionXML(path)) + { + this.error.setError("XD013", "Not XML file"); + return null; + } + xmlDoc = SignatureUtils.documentFromFile(path, options.XmlSchemaPath, this.error); + + } + else + { + xmlDoc = SignatureUtils.documentFromString(path, options.XmlSchemaPath, this.error); + } + return xmlDoc; + } } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/AsymmetricSigningAlgorithm.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/AsymmetricSigningAlgorithm.cs index dc2a65362..f0a5a935f 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/AsymmetricSigningAlgorithm.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/AsymmetricSigningAlgorithm.cs @@ -6,78 +6,78 @@ namespace GeneXusXmlSignature.GeneXusUtils { - /// - /// Implements AsymmetricSigningAlgorithm enumerated - /// - [SecuritySafeCritical] - public enum AsymmetricSigningAlgorithm - { + /// + /// Implements AsymmetricSigningAlgorithm enumerated + /// + [SecuritySafeCritical] + public enum AsymmetricSigningAlgorithm + { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - NONE, RSA, ECDSA + NONE, RSA, ECDSA #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - } + } - /// - /// Implements AsymmetricSigningAlgorithm assiciated functions - /// - [SecuritySafeCritical] - public static class AsymmetricSigningAlgorithmUtils - { + /// + /// Implements AsymmetricSigningAlgorithm assiciated functions + /// + [SecuritySafeCritical] + public static class AsymmetricSigningAlgorithmUtils + { - /// - /// Mapping between string name and AsymmetricSigningAlgorithm enum representation - /// - /// string asymmetricSigningAlgorithm - /// Error type for error management - /// AsymmetricSigningAlgorithm enum representation - public static AsymmetricSigningAlgorithm getAsymmetricSigningAlgorithm(string asymmetricSigningAlgorithm, Error error) - { - if(error == null) return AsymmetricSigningAlgorithm.NONE; - if ( asymmetricSigningAlgorithm == null) + /// + /// Mapping between string name and AsymmetricSigningAlgorithm enum representation + /// + /// string asymmetricSigningAlgorithm + /// Error type for error management + /// AsymmetricSigningAlgorithm enum representation + public static AsymmetricSigningAlgorithm getAsymmetricSigningAlgorithm(string asymmetricSigningAlgorithm, Error error) + { + if (error == null) return AsymmetricSigningAlgorithm.NONE; + if (asymmetricSigningAlgorithm == null) { - error.setError("AS001", "Unrecognized AsymmetricSigningAlgorithm"); + error.setError("ASA03", "Unrecognized AsymmetricSigningAlgorithm"); return AsymmetricSigningAlgorithm.NONE; } - switch (asymmetricSigningAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "RSA": - return AsymmetricSigningAlgorithm.RSA; - case "ECDSA": - return AsymmetricSigningAlgorithm.ECDSA; - default: - error.setError("AS001", "Unrecognized AsymmetricSigningAlgorithm"); - return AsymmetricSigningAlgorithm.NONE; - } - } - /// - /// Mapping between AsymmetricSigningAlgorithm enum representation and string name - /// - /// AsymmetricSigningAlgorithm enum, algorithm name - /// Error type for error management - /// string value of the algorithm - public static string valueOf(AsymmetricSigningAlgorithm asymmetricSigningAlgorithm, Error error) - { + switch (asymmetricSigningAlgorithm.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) + { + case "RSA": + return AsymmetricSigningAlgorithm.RSA; + case "ECDSA": + return AsymmetricSigningAlgorithm.ECDSA; + default: + error.setError("ASA01", "Unrecognized AsymmetricSigningAlgorithm"); + return AsymmetricSigningAlgorithm.NONE; + } + } + /// + /// Mapping between AsymmetricSigningAlgorithm enum representation and string name + /// + /// AsymmetricSigningAlgorithm enum, algorithm name + /// Error type for error management + /// string value of the algorithm + public static string valueOf(AsymmetricSigningAlgorithm asymmetricSigningAlgorithm, Error error) + { if (error == null) return ""; - switch (asymmetricSigningAlgorithm) - { - case AsymmetricSigningAlgorithm.RSA: - return "RSA"; - case AsymmetricSigningAlgorithm.ECDSA: - return "ECDSA"; - default: - error.setError("AS002", "Unrecognized AsymmetricSigningAlgorithm"); - return ""; - } - } + switch (asymmetricSigningAlgorithm) + { + case AsymmetricSigningAlgorithm.RSA: + return "RSA"; + case AsymmetricSigningAlgorithm.ECDSA: + return "ECDSA"; + default: + error.setError("ASA02", "Unrecognized AsymmetricSigningAlgorithm"); + return ""; + } + } - /// - /// Manage Enumerable enum - /// - /// AsymmetricSigningAlgorithm enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(AsymmetricSigningAlgorithm)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// AsymmetricSigningAlgorithm enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(AsymmetricSigningAlgorithm)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/CanonicalizerWrapper.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/CanonicalizerWrapper.cs index 62b3d31f7..5ab8d98b0 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/CanonicalizerWrapper.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/CanonicalizerWrapper.cs @@ -6,112 +6,112 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - public enum CanonicalizerWrapper - { + [SecuritySafeCritical] + public enum CanonicalizerWrapper + { #pragma warning disable CA1707 // Identifiers should not contain underscores NONE, ALGO_ID_C14N_WITH_COMMENTS, ALGO_ID_C14N_OMIT_COMMENTS, ALGO_ID_C14N_EXCL_OMIT_COMMENTS, ALGO_ID_C14N_EXCL_WITH_COMMENTS #pragma warning restore CA1707 // Identifiers should not contain underscores } - [SecuritySafeCritical] - public static class CanonicalizerWrapperUtils - { - public static CanonicalizerWrapper getCanonicalizerWrapper(string canonicalizerWrapper, Error error) - { - if(error == null) return CanonicalizerWrapper.NONE; - if ( canonicalizerWrapper == null) + [SecuritySafeCritical] + public static class CanonicalizerWrapperUtils + { + public static CanonicalizerWrapper getCanonicalizerWrapper(string canonicalizerWrapper, Error error) + { + if (error == null) return CanonicalizerWrapper.NONE; + if (canonicalizerWrapper == null) { - error.setError("CM001", "Unrecognized CanonicalizationMethod: " + canonicalizerWrapper); + error.setError("CAW05", "Unrecognized CanonicalizationMethod"); return CanonicalizerWrapper.NONE; } - switch (canonicalizerWrapper.Trim()) - { - case "C14n_WITH_COMMENTS": - return CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS; - case "C14n_OMIT_COMMENTS": - return CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS; - case "exc_C14n_OMIT_COMMENTS": - return CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; - case "exc_C14N_WITH_COMMENTS": - return CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS; - default: - error.setError("CM001", "Unrecognized CanonicalizationMethod: " + canonicalizerWrapper); - return CanonicalizerWrapper.NONE; - } - } + switch (canonicalizerWrapper.Trim()) + { + case "C14n_WITH_COMMENTS": + return CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS; + case "C14n_OMIT_COMMENTS": + return CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS; + case "exc_C14n_OMIT_COMMENTS": + return CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; + case "exc_C14N_WITH_COMMENTS": + return CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS; + default: + error.setError("CAW01", "Unrecognized CanonicalizationMethod"); + return CanonicalizerWrapper.NONE; + } + } - public static string valueOf(CanonicalizerWrapper canonicalizerWrapper, Error error) - { + public static string valueOf(CanonicalizerWrapper canonicalizerWrapper, Error error) + { if (error == null) return ""; - switch (canonicalizerWrapper) - { - case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: - return "C14n_WITH_COMMENTS"; - case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: - return "C14n_OMIT_COMMENTS"; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: - return "exc_C14n_OMIT_COMMENTS"; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: - return "exc_C14N_WITH_COMMENTS"; - default: - error.setError("CM002", "Unrecognized CanonicalizationMethod"); - return ""; - } - } + switch (canonicalizerWrapper) + { + case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: + return "C14n_WITH_COMMENTS"; + case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: + return "C14n_OMIT_COMMENTS"; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: + return "exc_C14n_OMIT_COMMENTS"; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: + return "exc_C14N_WITH_COMMENTS"; + default: + error.setError("CAW02", "Unrecognized CanonicalizationMethod"); + return ""; + } + } - public static string valueOfInternal(CanonicalizerWrapper canonicalizerWrapper, Error error) - { + public static string valueOfInternal(CanonicalizerWrapper canonicalizerWrapper, Error error) + { if (error == null) return ""; - switch (canonicalizerWrapper) - { - case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: - return "ALGO_ID_C14N_WITH_COMMENTS"; - case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: - return "ALGO_ID_C14N_OMIT_COMMENTS"; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: - return "ALGO_ID_C14N_EXCL_OMIT_COMMENTS"; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: - return "ALGO_ID_C14N_EXCL_WITH_COMMENTS"; - default: - error.setError("CM003", "Unrecognized CanonicalizationMethod"); - return ""; - } - } + switch (canonicalizerWrapper) + { + case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: + return "ALGO_ID_C14N_WITH_COMMENTS"; + case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: + return "ALGO_ID_C14N_OMIT_COMMENTS"; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: + return "ALGO_ID_C14N_EXCL_OMIT_COMMENTS"; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: + return "ALGO_ID_C14N_EXCL_WITH_COMMENTS"; + default: + error.setError("CAW03", "Unrecognized CanonicalizationMethod"); + return ""; + } + } - public static string getCanonicalizationMethodAlorithm(CanonicalizerWrapper canonicalizerWrapper, Error error) - { + public static string getCanonicalizationMethodAlorithm(CanonicalizerWrapper canonicalizerWrapper, Error error) + { if (error == null) return null; - switch (canonicalizerWrapper) - { - case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: - return Constants.ALGO_ID_C14N_WITH_COMMENTS; - case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: - return Constants.ALGO_ID_C14N_OMIT_COMMENTS; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: - return Constants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; - case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: - return Constants.ALGO_ID_C14N_EXCL_WITH_COMMENTS; - default: - error.setError("CM004", "Unrecognized CanonicalizationMethod"); - return null; + switch (canonicalizerWrapper) + { + case CanonicalizerWrapper.ALGO_ID_C14N_WITH_COMMENTS: + return Constants.ALGO_ID_C14N_WITH_COMMENTS; + case CanonicalizerWrapper.ALGO_ID_C14N_OMIT_COMMENTS: + return Constants.ALGO_ID_C14N_OMIT_COMMENTS; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_OMIT_COMMENTS: + return Constants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; + case CanonicalizerWrapper.ALGO_ID_C14N_EXCL_WITH_COMMENTS: + return Constants.ALGO_ID_C14N_EXCL_WITH_COMMENTS; + default: + error.setError("CAW04", "Unrecognized CanonicalizationMethod"); + return null; - } - } + } + } - /// - /// Manage Enumerable enum - /// - /// AsymmetricSigningAlgorithm enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(CanonicalizerWrapper)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// AsymmetricSigningAlgorithm enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(CanonicalizerWrapper)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/KeyInfoType.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/KeyInfoType.cs index 1ac9c6cfa..6a40c6b78 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/KeyInfoType.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/KeyInfoType.cs @@ -6,64 +6,64 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - public enum KeyInfoType - { - NONE, KeyValue, X509Certificate - } + [SecuritySafeCritical] + public enum KeyInfoType + { + NONE, KeyValue, X509Certificate + } - [SecuritySafeCritical] - public static class KeyInfoTypeUtils - { - public static KeyInfoType getKeyInfoType(string keyInfoType, Error error) - { - if(error == null) return KeyInfoType.NONE; + [SecuritySafeCritical] + public static class KeyInfoTypeUtils + { + public static KeyInfoType getKeyInfoType(string keyInfoType, Error error) + { + if (error == null) return KeyInfoType.NONE; if (keyInfoType == null) { - error.setError("KI001", "Unrecognized KeyInfoType"); + error.setError("KIT03", "Unrecognized KeyInfoType"); return KeyInfoType.NONE; } - switch (keyInfoType.Trim()) - { - case "NONE": - return KeyInfoType.NONE; - case "KeyValue": - return KeyInfoType.KeyValue; - case "X509Certificate": - return KeyInfoType.X509Certificate; - default: - error.setError("KI001", "Unrecognized KeyInfoType"); - return KeyInfoType.NONE; - } + switch (keyInfoType.Trim()) + { + case "NONE": + return KeyInfoType.NONE; + case "KeyValue": + return KeyInfoType.KeyValue; + case "X509Certificate": + return KeyInfoType.X509Certificate; + default: + error.setError("KIT01", "Unrecognized KeyInfoType"); + return KeyInfoType.NONE; + } - } + } - public static string valueOf(KeyInfoType keyInfoType, Error error) - { + public static string valueOf(KeyInfoType keyInfoType, Error error) + { if (error == null) return ""; - switch (keyInfoType) - { - case KeyInfoType.NONE: - return "NONE"; - case KeyInfoType.KeyValue: - return "KeyValue"; - case KeyInfoType.X509Certificate: - return "X509Certificate"; - default: - error.setError("KI002", "Unrecognized KeyInfoType"); - return ""; - } - } + switch (keyInfoType) + { + case KeyInfoType.NONE: + return "NONE"; + case KeyInfoType.KeyValue: + return "KeyValue"; + case KeyInfoType.X509Certificate: + return "X509Certificate"; + default: + error.setError("KIT02", "Unrecognized KeyInfoType"); + return ""; + } + } - /// - /// Manage Enumerable enum - /// - /// KeyInfoType enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(KeyInfoType)).Cast(); - } + /// + /// Manage Enumerable enum + /// + /// KeyInfoType enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(KeyInfoType)).Cast(); + } - } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/MessageDigestAlgorithmWrapper.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/MessageDigestAlgorithmWrapper.cs index 0def53d89..486986a7a 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/MessageDigestAlgorithmWrapper.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/MessageDigestAlgorithmWrapper.cs @@ -6,80 +6,81 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - public enum MessageDigestAlgorithmWrapper - { - NONE, SHA1, SHA256, SHA512, - } + [SecuritySafeCritical] + public enum MessageDigestAlgorithmWrapper + { + NONE, SHA1, SHA256, SHA512, + } - [SecuritySafeCritical] - public static class MessageDigestAlgorithmWrapperUtils - { - public static MessageDigestAlgorithmWrapper getMessageDigestAlgorithmWrapper(string messageDigestAlgorithmWrapper, - Error error) - { - if(error == null) return MessageDigestAlgorithmWrapper.NONE; + [SecuritySafeCritical] + public static class MessageDigestAlgorithmWrapperUtils + { + public static MessageDigestAlgorithmWrapper getMessageDigestAlgorithmWrapper(string messageDigestAlgorithmWrapper, + Error error) + { + if (error == null) return MessageDigestAlgorithmWrapper.NONE; if (messageDigestAlgorithmWrapper == null) { - error.setError("MD001", "Algorithm not found: " + messageDigestAlgorithmWrapper); + error.setError("MDA04", "Not recognized digest algorithm"); return MessageDigestAlgorithmWrapper.NONE; } - switch (messageDigestAlgorithmWrapper.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "SHA1": - return MessageDigestAlgorithmWrapper.SHA1; - case "SHA256": - return MessageDigestAlgorithmWrapper.SHA256; - case "SHA512": - return MessageDigestAlgorithmWrapper.SHA512; - default: - error.setError("MD001", "Algorithm not found: " + messageDigestAlgorithmWrapper); - return MessageDigestAlgorithmWrapper.NONE; - } - } + switch (messageDigestAlgorithmWrapper.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) + { + case "SHA1": + return MessageDigestAlgorithmWrapper.SHA1; + case "SHA256": + return MessageDigestAlgorithmWrapper.SHA256; + case "SHA512": + return MessageDigestAlgorithmWrapper.SHA512; + default: + error.setError("MDA01", "Not recognized digest algorithm"); + + return MessageDigestAlgorithmWrapper.NONE; + } + } - public static string valueOf(MessageDigestAlgorithmWrapper messageDigestAlgorithmWrapper, Error error) - { + public static string valueOf(MessageDigestAlgorithmWrapper messageDigestAlgorithmWrapper, Error error) + { if (error == null) return null; - switch (messageDigestAlgorithmWrapper) - { - case MessageDigestAlgorithmWrapper.SHA1: - return "SHA1"; - case MessageDigestAlgorithmWrapper.SHA256: - return "SHA256"; - case MessageDigestAlgorithmWrapper.SHA512: - return "SHA512"; - default: - error.setError("MD002", "Not recognized digest algorithm"); - return null; - } - } + switch (messageDigestAlgorithmWrapper) + { + case MessageDigestAlgorithmWrapper.SHA1: + return "SHA1"; + case MessageDigestAlgorithmWrapper.SHA256: + return "SHA256"; + case MessageDigestAlgorithmWrapper.SHA512: + return "SHA512"; + default: + error.setError("MDA02", "Not recognized digest algorithm"); + return null; + } + } - public static string getDigestMethod(MessageDigestAlgorithmWrapper messageDigestAlgorithmWrapper, Error error) - { + public static string getDigestMethod(MessageDigestAlgorithmWrapper messageDigestAlgorithmWrapper, Error error) + { if (error == null) return null; - switch (messageDigestAlgorithmWrapper) - { - case MessageDigestAlgorithmWrapper.SHA1: - return Constants.ALGO_ID_DIGEST_SHA1; - case MessageDigestAlgorithmWrapper.SHA256: - return Constants.ALGO_ID_DIGEST_SHA256; - case MessageDigestAlgorithmWrapper.SHA512: - return Constants.ALGO_ID_DIGEST_SHA512; - default: - error.setError("MD003", "Not recognized digest algorithm"); - return null; - } - } + switch (messageDigestAlgorithmWrapper) + { + case MessageDigestAlgorithmWrapper.SHA1: + return Constants.ALGO_ID_DIGEST_SHA1; + case MessageDigestAlgorithmWrapper.SHA256: + return Constants.ALGO_ID_DIGEST_SHA256; + case MessageDigestAlgorithmWrapper.SHA512: + return Constants.ALGO_ID_DIGEST_SHA512; + default: + error.setError("MDA03", "Not recognized digest algorithm"); + return null; + } + } - /// - /// Manage Enumerable enum - /// - /// AsymmetricSigningAlgorithm enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(MessageDigestAlgorithmWrapper)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// AsymmetricSigningAlgorithm enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(MessageDigestAlgorithmWrapper)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureElementType.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureElementType.cs index c61601cb8..374e79274 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureElementType.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureElementType.cs @@ -4,30 +4,30 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - public enum SignatureElementType - { - id, path, document - } + [SecuritySafeCritical] + public enum SignatureElementType + { + id, path, document + } - [SecuritySafeCritical] - public static class SignatureElementTypeUtils - { - public static string ValueOf(SignatureElementType signatureElementType, Error error) - { + [SecuritySafeCritical] + public static class SignatureElementTypeUtils + { + public static string ValueOf(SignatureElementType signatureElementType, Error error) + { if (error == null) return ""; - switch (signatureElementType) - { - case SignatureElementType.id: - return "id"; - case SignatureElementType.path: - return "path"; - case SignatureElementType.document: - return "document"; - default: - error.setError("SE001", "Unrecognized SignatureElementType"); - return ""; - } - } - } + switch (signatureElementType) + { + case SignatureElementType.id: + return "id"; + case SignatureElementType.path: + return "path"; + case SignatureElementType.document: + return "document"; + default: + error.setError("SET01", "Unrecognized SignatureElementType"); + return ""; + } + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureUtils.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureUtils.cs index 4e242e17e..fe7c117b6 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureUtils.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/SignatureUtils.cs @@ -8,10 +8,10 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - internal class SignatureUtils + [SecuritySafeCritical] + internal class SignatureUtils - { + { internal static XmlDocument documentFromFile(string path, string schemapath, Error error) { XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null }; @@ -32,35 +32,35 @@ internal static XmlDocument documentFromFile(string path, string schemapath, Err } } - - if (schemapath != null && !SecurityUtils.compareStrings(schemapath, "")) - { - if (!validateExtensionSchema(schemapath)) - { - error.setError("SU002", "The schema file should be an xsd, dtd or xml file"); - return null; - } - XmlSchemaSet schema = new XmlSchemaSet(); - XmlElement rootNode = (XmlElement)xmlDoc.DocumentElement; - schema.Add(rootNode.NamespaceURI, schemapath); - schema.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); - xmlDoc.Schemas = schema; - - try - { - xmlDoc.Validate(validationEventHandler); - } - catch (Exception e) - { - error.setError("SU003", e.Message); - return null; - } - } - return xmlDoc; - } - - internal static XmlDocument documentFromString(string xmlString, string schemapath, Error error) - { + + if (schemapath != null && !SecurityUtils.compareStrings(schemapath, "")) + { + if (!validateExtensionSchema(schemapath)) + { + error.setError("SU002", "The schema file should be an xsd, dtd or xml file"); + return null; + } + XmlSchemaSet schema = new XmlSchemaSet(); + XmlElement rootNode = (XmlElement)xmlDoc.DocumentElement; + schema.Add(rootNode.NamespaceURI, schemapath); + schema.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); + xmlDoc.Schemas = schema; + + try + { + xmlDoc.Validate(validationEventHandler); + } + catch (Exception e) + { + error.setError("SU003", e.Message); + return null; + } + } + return xmlDoc; + } + + internal static XmlDocument documentFromString(string xmlString, string schemapath, Error error) + { XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null }; @@ -81,93 +81,93 @@ internal static XmlDocument documentFromString(string xmlString, string schemapa } } } - if (schemapath != null && !SecurityUtils.compareStrings(schemapath, "")) - { - if (!validateExtensionSchema(schemapath)) - { - error.setError("SU004", "The schema file should be an xsd, dtd or xml file"); - return null; - } - XmlSchemaSet schema = new XmlSchemaSet(); - XmlElement rootNode = (XmlElement)xmlDoc.DocumentElement; - schema.Add(rootNode.NamespaceURI, schemapath); - schema.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); - xmlDoc.Schemas = schema; - - try - { - xmlDoc.Validate(validationEventHandler); - } - catch (Exception e) - { - error.setError("SU006", e.Message); - return null; - } - } - - return xmlDoc; - - } - - internal static string XMLDocumentToString(XmlDocument doc) - { - doc.PreserveWhitespace = true; - using (var stringWriter = new StringWriter()) - using (var xmlTextWriter = XmlWriter.Create(stringWriter)) - { - doc.WriteTo(xmlTextWriter); - xmlTextWriter.Flush(); - return stringWriter.GetStringBuilder().ToString(); - } - } - - public static bool writeToFile(string text, string path, string prefix, Error error) - { - try - { - - using (StreamWriter writetext = new StreamWriter(path)) - { - writetext.WriteLine(prefix + text); - } - } - catch (Exception) - { - error.setError("SU007", "Error writing file"); - return false; - } - return true; - - - } - - - internal static bool validateExtensionXML(string path) - { - if (SecurityUtils.extensionIs(path, ".xml")) - { - return true; - } - else - { - return false; - } - } - - internal static bool validateExtensionSchema(string path) - { - if (SecurityUtils.extensionIs(path, ".xsd") || SecurityUtils.extensionIs(path, ".xml") || SecurityUtils.extensionIs(path, ".dtd")) - { - return true; - } - else - { - return false; - } - } - - - /* internal static XmlNode getNodeFromID(XmlDocument doc, string id, string xPath, Error error) + if (schemapath != null && !SecurityUtils.compareStrings(schemapath, "")) + { + if (!validateExtensionSchema(schemapath)) + { + error.setError("SU004", "The schema file should be an xsd, dtd or xml file"); + return null; + } + XmlSchemaSet schema = new XmlSchemaSet(); + XmlElement rootNode = (XmlElement)xmlDoc.DocumentElement; + schema.Add(rootNode.NamespaceURI, schemapath); + schema.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); + xmlDoc.Schemas = schema; + + try + { + xmlDoc.Validate(validationEventHandler); + } + catch (Exception e) + { + error.setError("SU006", e.Message); + return null; + } + } + + return xmlDoc; + + } + + internal static string XMLDocumentToString(XmlDocument doc) + { + doc.PreserveWhitespace = true; + using (var stringWriter = new StringWriter()) + using (var xmlTextWriter = XmlWriter.Create(stringWriter)) + { + doc.WriteTo(xmlTextWriter); + xmlTextWriter.Flush(); + return stringWriter.GetStringBuilder().ToString(); + } + } + + public static bool writeToFile(string text, string path, string prefix, Error error) + { + try + { + + using (StreamWriter writetext = new StreamWriter(path)) + { + writetext.WriteLine(prefix + text); + } + } + catch (Exception) + { + error.setError("SU007", "Error writing file"); + return false; + } + return true; + + + } + + + internal static bool validateExtensionXML(string path) + { + if (SecurityUtils.extensionIs(path, ".xml")) + { + return true; + } + else + { + return false; + } + } + + internal static bool validateExtensionSchema(string path) + { + if (SecurityUtils.extensionIs(path, ".xsd") || SecurityUtils.extensionIs(path, ".xml") || SecurityUtils.extensionIs(path, ".dtd")) + { + return true; + } + else + { + return false; + } + } + + + /* internal static XmlNode getNodeFromID(XmlDocument doc, string id, string xPath, Error error) { if (id == null || SecurityUtils.compareStrings(id, "")) { @@ -198,129 +198,129 @@ internal static bool validateExtensionSchema(string path) return null; }*/ - internal static XmlNode getNodeFromID(XmlDocument doc, String id, String xPath, Error error) - { - if (id == null || SecurityUtils.compareStrings(id, "")) - { - error.setError("SU010", "Error, id data is empty"); - return null; - } - string idToFind = xPath.Substring(1); - XmlNode root = doc.DocumentElement; - XmlNodeList allNodes = root.ChildNodes; - - XmlNode n = RecursivegetNodeFromID(allNodes, id, idToFind); - if (n == null) - { - error.setError("SU009", "Could not find element with id " + idToFind); - } - return n; - - } - - private static XmlNode FindAttribute(XmlNode node, String id, String idToFind) - { - XmlAttributeCollection attributes = node.Attributes; - if (attributes != null) - { - foreach (XmlAttribute attribute in node.Attributes) - { - if (SecurityUtils.compareStrings(attribute.Name, id) && SecurityUtils.compareStrings(attribute.Value, idToFind)) - { - return node; - } - } - } - return null; - } - - private static XmlNode RecursivegetNodeFromID(XmlNodeList list, String id, String idToFind) - { - if (list.Count == 0) - { - return null; - } - else - { - for (int i = 0; i < list.Count; i++) - { - XmlNode node = FindAttribute(list.Item(i), id, idToFind); - if (node == null) - { - XmlNode n1 = RecursivegetNodeFromID(list.Item(i).ChildNodes, id, idToFind); - if (n1 != null) - { - return n1; - } - } - else - { - return node; - } - } - return null; - } - } - - - - internal static string getIDNodeValue(XmlDocument doc) - { - doc.PreserveWhitespace = true; - XmlNode rootNode = doc.DocumentElement; - XmlNodeList allNodes = rootNode.ChildNodes; - if (allNodes == null) - { - return ""; - } - foreach (XmlNode node in allNodes) - { - //java xmlsec hack - if (SecurityUtils.compareStrings("Reference", node.Name) || SecurityUtils.compareStrings("ds:Reference", node.Name)) - { - XmlAttributeCollection attributes = node.Attributes; - if (attributes == null) - { - return ""; - } - foreach (XmlAttribute attribute in attributes) - { - if (SecurityUtils.compareStrings("URI", attribute.Name)) - { - return attribute.Value; - } - } - - } - } - return ""; - } - - internal static XmlNode getNodeFromPath(XmlDocument doc, string expression, Error error) - { - doc.PreserveWhitespace = true; - try - { - return doc.SelectSingleNode(expression); - } - catch (Exception) - { - error.setError("SU008", "Could not found any node that matches de xPath predicate"); - return null; - } - } - - - - private static void validationEventHandler(object sender, ValidationEventArgs e) - { - XmlSeverityType type = XmlSeverityType.Warning; - if (Enum.TryParse("Error", out type)) - { - if (type == XmlSeverityType.Error) throw new Exception(e.Message); - } - } - - - } + internal static XmlNode getNodeFromID(XmlDocument doc, String id, String xPath, Error error) + { + if (id == null || SecurityUtils.compareStrings(id, "")) + { + error.setError("SU010", "Error, id data is empty"); + return null; + } + string idToFind = xPath.Substring(1); + XmlNode root = doc.DocumentElement; + XmlNodeList allNodes = root.ChildNodes; + + XmlNode n = RecursivegetNodeFromID(allNodes, id, idToFind); + if (n == null) + { + error.setError("SU009", "Could not find element with id " + idToFind); + } + return n; + + } + + private static XmlNode FindAttribute(XmlNode node, String id, String idToFind) + { + XmlAttributeCollection attributes = node.Attributes; + if (attributes != null) + { + foreach (XmlAttribute attribute in node.Attributes) + { + if (SecurityUtils.compareStrings(attribute.Name, id) && SecurityUtils.compareStrings(attribute.Value, idToFind)) + { + return node; + } + } + } + return null; + } + + private static XmlNode RecursivegetNodeFromID(XmlNodeList list, String id, String idToFind) + { + if (list.Count == 0) + { + return null; + } + else + { + for (int i = 0; i < list.Count; i++) + { + XmlNode node = FindAttribute(list.Item(i), id, idToFind); + if (node == null) + { + XmlNode n1 = RecursivegetNodeFromID(list.Item(i).ChildNodes, id, idToFind); + if (n1 != null) + { + return n1; + } + } + else + { + return node; + } + } + return null; + } + } + + + + internal static string getIDNodeValue(XmlDocument doc) + { + doc.PreserveWhitespace = true; + XmlNode rootNode = doc.DocumentElement; + XmlNodeList allNodes = rootNode.ChildNodes; + if (allNodes == null) + { + return null; + } + foreach (XmlNode node in allNodes) + { + //java xmlsec hack + if (SecurityUtils.compareStrings("Reference", node.Name) || SecurityUtils.compareStrings("ds:Reference", node.Name)) + { + XmlAttributeCollection attributes = node.Attributes; + if (attributes == null) + { + return null; + } + foreach (XmlAttribute attribute in attributes) + { + if (SecurityUtils.compareStrings("URI", attribute.Name)) + { + return attribute.Value; + } + } + + } + } + return null; + } + + internal static XmlNode getNodeFromPath(XmlDocument doc, string expression, Error error) + { + doc.PreserveWhitespace = true; + try + { + return doc.SelectSingleNode(expression); + } + catch (Exception) + { + error.setError("SU008", "Could not found any node that matches de xPath predicate"); + return null; + } + } + + + + private static void validationEventHandler(object sender, ValidationEventArgs e) + { + XmlSeverityType type = XmlSeverityType.Warning; + if (Enum.TryParse("Error", out type)) + { + if (type == XmlSeverityType.Error) throw new Exception(e.Message); + } + } + + + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/TransformsWrapper.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/TransformsWrapper.cs index b0db289a9..5c7a7af92 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/TransformsWrapper.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/TransformsWrapper.cs @@ -6,87 +6,87 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - public enum TransformsWrapper - { - NONE, ENVELOPED, ENVELOPING, DETACHED, - } + [SecuritySafeCritical] + public enum TransformsWrapper + { + NONE, ENVELOPED, ENVELOPING, DETACHED, + } - [SecuritySafeCritical] - public static class TransformsWrapperUtils - { - public static TransformsWrapper getTransformsWrapper(string transformsWrapper, Error error) - { - if(error == null) return TransformsWrapper.NONE; - if ( transformsWrapper == null) + [SecuritySafeCritical] + public static class TransformsWrapperUtils + { + public static TransformsWrapper getTransformsWrapper(string transformsWrapper, Error error) + { + if (error == null) return TransformsWrapper.NONE; + if (transformsWrapper == null) { - error.setError("TW001", "Unrecognized transformation: " + transformsWrapper); + error.setError("TRW04", "Unrecognized transformation"); return TransformsWrapper.NONE; } - switch (transformsWrapper.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "ENVELOPED": - return TransformsWrapper.ENVELOPED; - case "ENVELOPING": - return TransformsWrapper.ENVELOPING; - case "DETACHED": - return TransformsWrapper.DETACHED; - default: - error.setError("TW001", "Unrecognized transformation: " + transformsWrapper); - return TransformsWrapper.NONE; - } - } + switch (transformsWrapper.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) + { + case "ENVELOPED": + return TransformsWrapper.ENVELOPED; + case "ENVELOPING": + return TransformsWrapper.ENVELOPING; + case "DETACHED": + return TransformsWrapper.DETACHED; + default: + error.setError("TRW01", "Unrecognized transformation"); + return TransformsWrapper.NONE; + } + } - public static string valueOf(TransformsWrapper transformsWrapper, Error error) - { + public static string valueOf(TransformsWrapper transformsWrapper, Error error) + { if (error == null) return null; - switch (transformsWrapper) - { - case TransformsWrapper.ENVELOPED: - return "ENVELOPED"; - case TransformsWrapper.ENVELOPING: - return "ENVELOPING"; - case TransformsWrapper.DETACHED: - return "DETACHED"; - default: - error.setError("TW002", "Unrecognized transformation"); - return null; - } - } + switch (transformsWrapper) + { + case TransformsWrapper.ENVELOPED: + return "ENVELOPED"; + case TransformsWrapper.ENVELOPING: + return "ENVELOPING"; + case TransformsWrapper.DETACHED: + return "DETACHED"; + default: + error.setError("TRW02", "Unrecognized transformation"); + return null; + } + } - public static string getSignatureTypeTransform(TransformsWrapper transformsWrapper, Error error) - { + public static string getSignatureTypeTransform(TransformsWrapper transformsWrapper, Error error) + { if (error == null) return null; - switch (transformsWrapper) - { - case TransformsWrapper.ENVELOPED: - return Constants.TRANSFORM_ENVELOPED_SIGNATURE; - case TransformsWrapper.ENVELOPING: - return "http://www.w3.org/2000/09/xmldsig#enveloping-signature"; - case TransformsWrapper.DETACHED: - return "http://www.w3.org/2000/09/xmldsig#detached-signature"; - default: - error.setError("TW003", "Unrecognized transformation"); - return null; + switch (transformsWrapper) + { + case TransformsWrapper.ENVELOPED: + return Constants.TRANSFORM_ENVELOPED_SIGNATURE; + case TransformsWrapper.ENVELOPING: + return "http://www.w3.org/2000/09/xmldsig#enveloping-signature"; + case TransformsWrapper.DETACHED: + return "http://www.w3.org/2000/09/xmldsig#detached-signature"; + default: + error.setError("TRW03", "Unrecognized transformation"); + return null; - } - } + } + } - public static string getCanonicalizationTransformation(CanonicalizerWrapper canonicalizerWrapper, Error error) - { - return CanonicalizerWrapperUtils.getCanonicalizationMethodAlorithm(canonicalizerWrapper, error); - } + public static string getCanonicalizationTransformation(CanonicalizerWrapper canonicalizerWrapper, Error error) + { + return CanonicalizerWrapperUtils.getCanonicalizationMethodAlorithm(canonicalizerWrapper, error); + } - /// - /// Manage Enumerable enum - /// - /// TransformsWrapper enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(TransformsWrapper)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// TransformsWrapper enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(TransformsWrapper)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/XmlSignatureWrapper.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/XmlSignatureWrapper.cs index c19c0d4fb..171958b1b 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/XmlSignatureWrapper.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/Utils/XmlSignatureWrapper.cs @@ -6,98 +6,98 @@ namespace GeneXusXmlSignature.GeneXusUtils { - [SecuritySafeCritical] - public enum XmlSignatureWrapper - { + [SecuritySafeCritical] + public enum XmlSignatureWrapper + { #pragma warning disable CA1707 // Identifiers should not contain underscores NONE, RSA_SHA1, RSA_SHA256, RSA_SHA512, ECDSA_SHA1, ECDSA_SHA256, #pragma warning restore CA1707 // Identifiers should not contain underscores } - [SecuritySafeCritical] - public static class XMLSignatureWrapperUtils - { - public static XmlSignatureWrapper getXMLSignatureWrapper(string xMLSignatureWrapper, Error error) - { - if(error == null) return XmlSignatureWrapper.NONE; + [SecuritySafeCritical] + public static class XMLSignatureWrapperUtils + { + public static XmlSignatureWrapper getXMLSignatureWrapper(string xMLSignatureWrapper, Error error) + { + if (error == null) return XmlSignatureWrapper.NONE; if (xMLSignatureWrapper == null) { - error.setError("XS001", "Unrecognized algorithm: " + xMLSignatureWrapper); + error.setError("XSW04", "Unrecognized algorithm"); return XmlSignatureWrapper.NONE; } - switch (xMLSignatureWrapper.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) - { - case "RSA_SHA1": - return XmlSignatureWrapper.RSA_SHA1; - case "RSA_SHA256": - return XmlSignatureWrapper.RSA_SHA256; - case "RSA_SHA512": - return XmlSignatureWrapper.RSA_SHA512; - case "ECDSA_SHA1": - return XmlSignatureWrapper.ECDSA_SHA1; - case "ECDSA_SHA256": - return XmlSignatureWrapper.ECDSA_SHA256; - default: - error.setError("XS001", "Unrecognized algorithm: " + xMLSignatureWrapper); - return XmlSignatureWrapper.NONE; - } - } + switch (xMLSignatureWrapper.ToUpper(System.Globalization.CultureInfo.InvariantCulture).Trim()) + { + case "RSA_SHA1": + return XmlSignatureWrapper.RSA_SHA1; + case "RSA_SHA256": + return XmlSignatureWrapper.RSA_SHA256; + case "RSA_SHA512": + return XmlSignatureWrapper.RSA_SHA512; + case "ECDSA_SHA1": + return XmlSignatureWrapper.ECDSA_SHA1; + case "ECDSA_SHA256": + return XmlSignatureWrapper.ECDSA_SHA256; + default: + error.setError("XSW01", "Unrecognized algorithm"); + return XmlSignatureWrapper.NONE; + } + } - public static string valueOf(XmlSignatureWrapper xMLSignatureWrapper, Error error) - { + public static string valueOf(XmlSignatureWrapper xMLSignatureWrapper, Error error) + { if (error == null) return null; - switch (xMLSignatureWrapper) - { - case XmlSignatureWrapper.RSA_SHA1: - return "RSA_SHA1"; - case XmlSignatureWrapper.RSA_SHA256: - return "RSA_SHA256"; - case XmlSignatureWrapper.RSA_SHA512: - return "RSA_SHA512"; - case XmlSignatureWrapper.ECDSA_SHA1: - return "ECDSA_SHA1"; - case XmlSignatureWrapper.ECDSA_SHA256: - return "ECDSA_SHA256"; - default: - error.setError("XS002", "Unrecognized algorithm"); - return null; - } - } + switch (xMLSignatureWrapper) + { + case XmlSignatureWrapper.RSA_SHA1: + return "RSA_SHA1"; + case XmlSignatureWrapper.RSA_SHA256: + return "RSA_SHA256"; + case XmlSignatureWrapper.RSA_SHA512: + return "RSA_SHA512"; + case XmlSignatureWrapper.ECDSA_SHA1: + return "ECDSA_SHA1"; + case XmlSignatureWrapper.ECDSA_SHA256: + return "ECDSA_SHA256"; + default: + error.setError("XSW02", "Unrecognized algorithm"); + return null; + } + } - public static string getSignatureMethodAlgorithm(XmlSignatureWrapper xMLSignatureWrapper, Error error) - { + public static string getSignatureMethodAlgorithm(XmlSignatureWrapper xMLSignatureWrapper, Error error) + { if (error == null) return null; - switch (xMLSignatureWrapper) - { - case XmlSignatureWrapper.RSA_SHA1: - return Constants.ALGO_ID_SIGNATURE_RSA_SHA1; - case XmlSignatureWrapper.RSA_SHA256: - return Constants.ALGO_ID_SIGNATURE_RSA_SHA256; - case XmlSignatureWrapper.RSA_SHA512: - return Constants.ALGO_ID_SIGNATURE_RSA_SHA512; - case XmlSignatureWrapper.ECDSA_SHA1: - return Constants.ALGO_ID_SIGNATURE_ECDSA_SHA1; - case XmlSignatureWrapper.ECDSA_SHA256: - return Constants.ALGO_ID_SIGNATURE_ECDSA_SHA256; - default: - error.setError("XS003", "Unrecognized algorithm"); - return null; - } - } + switch (xMLSignatureWrapper) + { + case XmlSignatureWrapper.RSA_SHA1: + return Constants.ALGO_ID_SIGNATURE_RSA_SHA1; + case XmlSignatureWrapper.RSA_SHA256: + return Constants.ALGO_ID_SIGNATURE_RSA_SHA256; + case XmlSignatureWrapper.RSA_SHA512: + return Constants.ALGO_ID_SIGNATURE_RSA_SHA512; + case XmlSignatureWrapper.ECDSA_SHA1: + return Constants.ALGO_ID_SIGNATURE_ECDSA_SHA1; + case XmlSignatureWrapper.ECDSA_SHA256: + return Constants.ALGO_ID_SIGNATURE_ECDSA_SHA256; + default: + error.setError("XSW03", "Unrecognized algorithm"); + return null; + } + } - public static string getCanonicalizationTransformation(XmlSignatureWrapper xMLSignatureWrapper, Error error) - { - return XMLSignatureWrapperUtils.valueOf(xMLSignatureWrapper, error); - } + public static string getCanonicalizationTransformation(XmlSignatureWrapper xMLSignatureWrapper, Error error) + { + return XMLSignatureWrapperUtils.valueOf(xMLSignatureWrapper, error); + } - /// - /// Manage Enumerable enum - /// - /// XMLSignatureWrapper enum - /// Enumerated values - internal static IEnumerable GetValues() - { - return Enum.GetValues(typeof(XMLSignatureWrapper)).Cast(); - } - } + /// + /// Manage Enumerable enum + /// + /// XMLSignatureWrapper enum + /// Enumerated values + internal static IEnumerable GetValues() + { + return Enum.GetValues(typeof(XMLSignatureWrapper)).Cast(); + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/Base64Encoder.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/Base64Encoder.cs index 59b4a76ad..50b2e87a2 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/Base64Encoder.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/Base64Encoder.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; using System.Security; using SecurityAPICommons.Commons; using SecurityAPICommons.Config; @@ -10,110 +6,141 @@ namespace SecurityAPICommons.Encoders { - /// - /// Base64Encoder class - /// - [SecuritySafeCritical] - public class Base64Encoder : SecurityAPIObject - { + /// + /// Base64Encoder class + /// + [SecuritySafeCritical] + public class Base64Encoder : SecurityAPIObject + { - /// - /// Base64Encoder constructor - /// - [SecuritySafeCritical] - public Base64Encoder() : base() - { + /// + /// Base64Encoder constructor + /// + [SecuritySafeCritical] + public Base64Encoder() : base() + { - } + } - /// - /// string to Base64 encoded string - /// - /// string UTF-8 plain text to encode - /// Base64 string text encoded - [SecuritySafeCritical] - public string toBase64(string text) - { - EncodingUtil eu = new EncodingUtil(); - byte[] textBytes = eu.getBytes(text); - if (eu.HasError()) - { - this.error = eu.error; - return ""; + /// + /// string to Base64 encoded string + /// + /// string UTF-8 plain text to encode + /// Base64 string text encoded + [SecuritySafeCritical] + public string toBase64(string text) + { + this.error.cleanError(); + EncodingUtil eu = new EncodingUtil(); + byte[] textBytes = eu.getBytes(text); + if (eu.HasError()) + { + this.error = eu.GetError(); + return ""; + } + string result = ""; + try + { + result = Base64.ToBase64String(textBytes); + } + catch (Exception e) + { + this.error.setError("BS001", e.Message); + return ""; + } + return result; + } + /// + /// string Base64 encoded to string plain text + /// + /// string Base64 encoded + /// string UTF-8 plain text from Base64 + [SecuritySafeCritical] + public string toPlainText(string base64Text) + { + this.error.cleanError(); + byte[] bytes; + try + { + bytes = Base64.Decode(base64Text); + } + catch (Exception e) + { + this.error.setError("BS002", e.Message); + return ""; + } + EncodingUtil eu = new EncodingUtil(); + string result = eu.getString(bytes); + if (eu.HasError()) + { + this.error = eu.GetError(); + return ""; + } + return result; + } + /// + /// string Base64 encoded text to string hexadecimal encoded text + /// + /// string Base64 encoded + /// string Hexa representation of base64Text + [SecuritySafeCritical] + public string toStringHexa(string base64Text) + { + this.error.cleanError(); + byte[] bytes; + try + { + bytes = Base64.Decode(base64Text); + } + catch (Exception e) + { + this.error.setError("BS003", e.Message); + return ""; + } + string result = ""; + try + { + result = Hex.ToHexString(bytes).ToUpper(); + } + catch (Exception e) + { + this.error.setError("BS004", e.Message); + return ""; + } + return result; - } - - string result = System.Text.Encoding.UTF8.GetString(Base64.Encode(textBytes)); - if (result == null || result.Length == 0) - { - this.error.setError("B64001", "Error encoding base64"); - return ""; - } - this.error.cleanError(); - return result; - } - /// - /// string Base64 encoded to string plain text - /// - /// string Base64 encoded - /// string UTF-8 plain text from Base64 - [SecuritySafeCritical] - public string toPlainText(string base64Text) - { - EncodingUtil eu = new EncodingUtil(); - byte[] bytes = Base64.Decode(base64Text); - string result = eu.getString(bytes); - if (eu.HasError()) - { - this.error = eu.error; - return ""; - } - if (result == null || result.Length == 0) - { - this.error.setError("B64002", "Error decoding base64"); - return ""; - } - this.error.cleanError(); - return result; - } - /// - /// string Base64 encoded text to string hexadecimal encoded text - /// - /// string Base64 encoded - /// string Hexa representation of base64Text - [SecuritySafeCritical] - public string toStringHexa(string base64Text) - { - - byte[] bytes = Base64.Decode(base64Text); - string result = BitConverter.ToString(bytes).Replace("-", string.Empty); - if (result == null || result.Length == 0) - { - this.error.setError("B64003", "Error decoding base64 to hexa"); - return ""; - } - this.error.cleanError(); - return result; - - } - /// - /// string hexadecimal encoded text to string Base64 encoded text - /// - /// string Hexa - /// string Base64 encoded of stringHexa - [SecuritySafeCritical] - public string fromStringHexaToBase64(string stringHexa) - { - byte[] stringBytes = Hex.Decode(stringHexa); - string result = System.Text.Encoding.UTF8.GetString((Base64.Encode(stringBytes))); - if (result == null || result.Length == 0) - { - this.error.setError("B64004", "Error encoding base64 from hexa"); - return ""; - } - this.error.cleanError(); - return result; - } - } + } + /// + /// string hexadecimal encoded text to string Base64 encoded text + /// + /// string Hexa + /// string Base64 encoded of stringHexa + [SecuritySafeCritical] + public string fromStringHexaToBase64(string stringHexa) + { + this.error.cleanError(); + byte[] stringBytes; + try + { + stringBytes = Hex.Decode(stringHexa); + } + catch (Exception e) + { + this.error.setError("BS005", e.Message); + return ""; + } + string result = ""; + try + { + result = Base64.ToBase64String(stringBytes); + } + catch (Exception e) + { + this.error.setError("BS006", e.Message); + return ""; + } + return result; + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/HexaEncoder.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/HexaEncoder.cs index ea0163672..949fdc793 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/HexaEncoder.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Encoders/HexaEncoder.cs @@ -1,6 +1,5 @@ using SecurityAPICommons.Commons; using SecurityAPICommons.Config; -using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; using System; using System.Security; @@ -8,79 +7,84 @@ namespace SecurityAPICommons.Encoders { - /// - /// Implements hexadecimal encoding and decoding functions - /// - [SecuritySafeCritical] - public class HexaEncoder : SecurityAPIObject - { + /// + /// Implements hexadecimal encoding and decoding functions + /// + [SecuritySafeCritical] + public class HexaEncoder : SecurityAPIObject + { - /// - /// Hexa class contructor - /// + /// + /// Hexa class contructor + /// - [SecuritySafeCritical] - public HexaEncoder() : base() - { - - } - - /// - /// string Hexadecimal encoded representation of UTF-8 input plain text - /// - /// string UTF-8 plain text - /// string Hexa hexadecimal representation of plainText - [SecuritySafeCritical] - public string toHexa(string plainText) - { - EncodingUtil eu = new EncodingUtil(); - byte[] stringBytes = eu.getBytes(plainText); - if (eu.HasError()) - { - this.error = eu.GetError(); - return ""; - } - string result = BitConverter.ToString(stringBytes).Replace("-", string.Empty); - if (result == null || result.Length == 0) - { - this.error.setError("HE001", "Error encoding hexa"); - return ""; - } - this.error.cleanError(); - return result; + [SecuritySafeCritical] + public HexaEncoder() : base() + { - } - /// - /// string UTF-8 representation of the STring hexadecimal encoded text - /// - /// string hexadecimal representation of a text - /// string UTF-8 plain text from stringHexa - [SecuritySafeCritical] - public string fromHexa(string stringHexa) - { - byte[] stringBytes = Hex.Decode(stringHexa); + } - //string result = Strings.FromByteArray(stringBytes); + /// + /// string Hexadecimal encoded representation of UTF-8 input plain text + /// + /// string UTF-8 plain text + /// string Hexa hexadecimal representation of plainText + [SecuritySafeCritical] + public string toHexa(string plainText) + { + this.error.cleanError(); + EncodingUtil eu = new EncodingUtil(); + byte[] stringBytes = eu.getBytes(plainText); + if (eu.HasError()) + { + this.error = eu.GetError(); + return ""; + } + string hexa = ""; + try + { + hexa = Hex.ToHexString(stringBytes, 0, stringBytes.Length); + } + catch (Exception e) + { + this.error.setError("HE001", e.Message); + return ""; + } + return hexa.ToUpper(); - EncodingUtil eu = new EncodingUtil(); - String result = eu.getString(stringBytes); - if (eu.HasError()) - { - this.error = eu.GetError(); - return ""; - } - if (result == null || result.Length == 0) - { - this.error.setError("HE002", "Error decoding hexa"); - return ""; - } - this.error.cleanError(); - return result; - } + } + /// + /// string UTF-8 representation of the STring hexadecimal encoded text + /// + /// string hexadecimal representation of a text + /// string UTF-8 plain text from stringHexa + [SecuritySafeCritical] + public string fromHexa(string stringHexa) + { + this.error.cleanError(); + byte[] resBytes; + try + { + resBytes = Hex.Decode(fixString(stringHexa)); + } + catch (Exception e) + { + this.error.setError("HE002", e.Message); + return ""; + } + EncodingUtil eu = new EncodingUtil(); + String result = eu.getString(resBytes); + if (eu.HasError()) + { + this.error = eu.GetError(); + return ""; + } + return result; + } [SecuritySafeCritical] - public bool isHexa(String input) + public bool isHexa(string input) { this.error.cleanError(); try @@ -94,7 +98,7 @@ public bool isHexa(String input) return true; } - private String fixString(String input) + public static string fixString(String input) { if (!input.Contains("-")) { @@ -102,7 +106,7 @@ private String fixString(String input) } else { - String inputStr = input.Replace("-", ""); + string inputStr = input.Replace("-", ""); return inputStr; } } diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Utils/SecurityUtils.cs b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Utils/SecurityUtils.cs index 5cf53276c..741e6ed04 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Utils/SecurityUtils.cs +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/Utils/SecurityUtils.cs @@ -1,35 +1,36 @@ using Org.BouncyCastle.Utilities.Encoders; using SecurityAPICommons.Commons; +using SecurityAPICommons.Config; using System; using System.IO; using System.Security; namespace SecurityAPICommons.Utils { - [SecuritySafeCritical] - public static class SecurityUtils - { - - /// - /// Compares two strings ignoring casing - /// - /// string to compare - /// string to compare - /// true if both strings are equal ignoring casing - [SecuritySafeCritical] - public static bool compareStrings(string one, string two) - { - if(one != null && two != null) - { - return string.Compare(one, two, true, System.Globalization.CultureInfo.InvariantCulture) == 0; - } - else - { - return false; - } - - } + [SecuritySafeCritical] + public static class SecurityUtils + { + + /// + /// Compares two strings ignoring casing + /// + /// string to compare + /// string to compare + /// true if both strings are equal ignoring casing + [SecuritySafeCritical] + public static bool compareStrings(string one, string two) + { + if (one != null && two != null) + { + return string.Compare(one, two, true, System.Globalization.CultureInfo.InvariantCulture) == 0; + } + else + { + return false; + } + + } [SecuritySafeCritical] public static byte[] getFileBytes(string path, Error error) @@ -59,11 +60,11 @@ public static Stream getFileStream(string pathInput, Error error) } catch (Exception e) { - if(error != null) + if (error != null) { error.setError("SU002", e.Message); } - + } return aux; } @@ -75,35 +76,35 @@ public static Stream getFileStream(string pathInput, Error error) /// extension of the file /// true if the file has the extension [SecuritySafeCritical] - public static bool extensionIs(string path, string ext) - { - return string.Compare(getFileExtension(path), ext, true, System.Globalization.CultureInfo.InvariantCulture) == 0; - } - /// - /// Gets a file extension from the file's path - /// - /// path to the file - /// file extension - [SecuritySafeCritical] - public static string getFileExtension(string path) - { - - string fileName = Path.GetFileName(path); - string extension; + public static bool extensionIs(string path, string ext) + { + return string.Compare(getFileExtension(path), ext, true, System.Globalization.CultureInfo.InvariantCulture) == 0; + } + /// + /// Gets a file extension from the file's path + /// + /// path to the file + /// file extension + [SecuritySafeCritical] + public static string getFileExtension(string path) + { + + string fileName = Path.GetFileName(path); + string extension; try { - extension = Path.GetExtension(fileName); - } - catch(Exception) + extension = Path.GetExtension(fileName); + } + catch (Exception) { - extension = ""; + extension = ""; } - return extension; - } + return extension; + } [SecuritySafeCritical] - public static byte[] GetHexa(string hex, string code, Error error) + public static byte[] HexaToByte(string hex, Error error) { if (error == null) return null; byte[] output; @@ -111,11 +112,65 @@ public static byte[] GetHexa(string hex, string code, Error error) { output = Hex.Decode(hex); } - catch (Exception e) { - error.setError(code, e.Message); + catch (Exception e) + { + error.setError("SU004", e.Message); return null; } return output; } + + public static Stream StringToStream(String input, Error error) + { + EncodingUtil eu = new EncodingUtil(); + byte[] inputText = eu.getBytes(input); + if (eu.HasError()) + { + error = eu.GetError(); + return null; + } + else + { + try + { + using (Stream inputStream = new MemoryStream(inputText)) + { + return inputStream; + } + } + catch (Exception e) + { + error.setError("SU003", e.Message); + return null; + } + + } + } + + public static bool validateStringInput(string name, string value, Error error) + { + if (value == null) + { + error.setError("SU005", String.Format("The parameter %s cannot be empty", name)); + return false; + } + if (value.Length == 0) + { + error.setError("SU006", String.Format("The parameter %s cannot be empty", name)); + return false; + } + return true; + } + + public static bool validateObjectInput(string name, Object value, Error error) + { + if (value == null) + { + error.setError("SU007", String.Format("The parameter %a cannot be empty", name)); + return false; + } + return true; + } + } } diff --git a/dotnet/src/extensions/SecurityAPI/test/dotnetcore/SecurityAPITestNetCore/SecurityAPITestNetCore.csproj b/dotnet/src/extensions/SecurityAPI/test/dotnetcore/SecurityAPITestNetCore/SecurityAPITestNetCore.csproj index fb0d25037..548e59c47 100644 --- a/dotnet/src/extensions/SecurityAPI/test/dotnetcore/SecurityAPITestNetCore/SecurityAPITestNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/test/dotnetcore/SecurityAPITestNetCore/SecurityAPITestNetCore.csproj @@ -22,6 +22,7 @@ + @@ -30,6 +31,7 @@ + @@ -49,6 +51,7 @@ + @@ -56,12 +59,12 @@ - + - + diff --git a/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryption.cs b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryption.cs index f4c553f66..a199dd10b 100644 --- a/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryption.cs +++ b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryption.cs @@ -93,7 +93,7 @@ protected virtual void SetUp() arrayTagsCCM = new int[] { 64, 128 }; arrayMacsEAX = new int[] { 8, 16, 64, 128 }; arrayNonces = new string[] { IV64, IV128, IV192, IV256 }; - arrayModes_160_224 = new string[] { "ECB"/*, "CBC", "CTR", "CTS", "OPENPGPCFB" */}; //CFB mode does not work on 160 and 224 block sizes + arrayModes_160_224 = new string[] { "ECB", "CBC", "CTR", "CTS", "OPENPGPCFB" }; //CFB mode does not work on 160 and 224 block sizes encodings = new string[] { "UTF_8", "UTF_16", "UTF_16BE", "UTF_16LE", "UTF_32", "UTF_32BE", "UTF_32LE", "SJIS", "GB2312" }; diff --git a/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryptionFiles.cs b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryptionFiles.cs new file mode 100644 index 000000000..4d4b4988a --- /dev/null +++ b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Cryptography/Symmetric/TestBlockEncryptionFiles.cs @@ -0,0 +1,192 @@ +using System; +using System.IO; +using GeneXusCryptography.Checksum; +using GeneXusCryptography.Symmetric; +using NUnit.Framework; +using SecurityAPICommons.Keys; +using SecurityAPITest.SecurityAPICommons.commons; + +namespace SecurityAPITest.Cryptography.Symmetric +{ + [TestFixture] + public class TestBlockEncryptionFiles : SecurityAPITestObject + { + + protected static string key256; + protected static string key192; + protected static string key160; + protected static string key128; + protected static string key64; + + protected static string IV256; + protected static string IV224; + protected static string IV192; + protected static string IV160; + protected static string IV128; + protected static string IV64; + + private static SymmetricKeyGenerator keyGen; + + protected static string pathInput; + protected static string pathOutputEncrypted; + protected static string pathOutput; + + [SetUp] + protected virtual void SetUp() + { + pathInput = Path.Combine(BASE_PATH, "Temp", "flag.jpg"); + pathOutputEncrypted = Path.Combine(BASE_PATH, "Temp", "flagEncrypted"); + pathOutput = Path.Combine(BASE_PATH, "Temp", "flagOut.jpg"); + + keyGen = new SymmetricKeyGenerator(); + + /**** CREATE KEYS ****/ + key256 = keyGen.doGenerateKey("GENERICRANDOM", 256); + key160 = keyGen.doGenerateKey("GENERICRANDOM", 160); + key192 = keyGen.doGenerateKey("GENERICRANDOM", 192); + key128 = keyGen.doGenerateKey("GENERICRANDOM", 128); + key64 = keyGen.doGenerateKey("GENERICRANDOM", 64); + + /**** CREATE IVs ****/ + IV256 = keyGen.doGenerateIV("GENERICRANDOM", 256); + IV224 = keyGen.doGenerateIV("GENERICRANDOM", 224); + IV192 = keyGen.doGenerateIV("GENERICRANDOM", 192); + IV160 = keyGen.doGenerateIV("GENERICRANDOM", 160); + IV128 = keyGen.doGenerateIV("GENERICRANDOM", 128); + IV64 = keyGen.doGenerateIV("GENERICRANDOM", 64); + } + + [Test] + public void TestAES() + { + TestBulkFiles("AES", "CBC", "ZEROBYTEPADDING", key128, IV128); + TestBulkFiles("AES", "CBC", "ZEROBYTEPADDING", key192, IV128); + TestBulkFiles("AES", "CBC", "ZEROBYTEPADDING", key256, IV128); + + TestBulkFiles("AES", "ECB", "ZEROBYTEPADDING", key128, IV128); + TestBulkFiles("AES", "ECB", "ZEROBYTEPADDING", key192, IV128); + TestBulkFiles("AES", "ECB", "ZEROBYTEPADDING", key256, IV128); + + TestBulkFiles("AES", "CBC", "PKCS7PADDING", key128, IV128); + TestBulkFiles("AES", "CBC", "PKCS7PADDING", key192, IV128); + TestBulkFiles("AES", "CBC", "PKCS7PADDING", key256, IV128); + + TestBulkFiles("AES", "CBC", "X923PADDING", key128, IV128); + TestBulkFiles("AES", "CBC", "X923PADDING", key192, IV128); + TestBulkFiles("AES", "CBC", "X923PADDING", key256, IV128); + + TestBulkFiles("AES", "CBC", "ISO7816D4PADDING", key128, IV128); + TestBulkFiles("AES", "CBC", "ISO7816D4PADDING", key192, IV128); + TestBulkFiles("AES", "CBC", "ISO7816D4PADDING", key256, IV128); + + TestBulkGCM("AES", key128, IV128); + TestBulkGCM("AES", key192, IV128); + TestBulkGCM("AES", key256, IV128); + } + + [Test] + public void TestDES() + { + TestBulkFiles("DES", "CBC", "ZEROBYTEPADDING", key64, IV64); + } + + [Test] + public void TestTRIPLEDES() + { + TestBulkFiles("TRIPLEDES", "CBC", "ZEROBYTEPADDING", key128, IV64); + TestBulkFiles("TRIPLEDES", "CBC", "ZEROBYTEPADDING", key192, IV64); + } + + [Test] + public void TestRIJNDAEL() + { + TestBulkFiles("RIJNDAEL_128", "CBC", "ZEROBYTEPADDING", key128, IV128); + TestBulkFiles("RIJNDAEL_128", "CBC", "ZEROBYTEPADDING", key256, IV128); + TestBulkFiles("RIJNDAEL_256", "CBC", "ZEROBYTEPADDING", key128, IV256); + TestBulkFiles("RIJNDAEL_256", "CBC", "ZEROBYTEPADDING", key256, IV256); + + TestBulkFiles("RIJNDAEL_128", "ECB", "ZEROBYTEPADDING", key128, IV128); + TestBulkFiles("RIJNDAEL_128", "ECB", "ZEROBYTEPADDING", key256, IV128); + TestBulkFiles("RIJNDAEL_256", "ECB", "ZEROBYTEPADDING", key128, IV256); + TestBulkFiles("RIJNDAEL_256", "ECB", "ZEROBYTEPADDING", key256, IV256); + + TestBulkFiles("RIJNDAEL_128", "CBC", "PKCS7PADDING", key128, IV128); + TestBulkFiles("RIJNDAEL_128", "CBC", "PKCS7PADDING", key256, IV128); + TestBulkFiles("RIJNDAEL_256", "CBC", "PKCS7PADDING", key128, IV256); + TestBulkFiles("RIJNDAEL_256", "CBC", "PKCS7PADDING", key256, IV256); + + TestBulkFiles("RIJNDAEL_128", "CBC", "X923PADDING", key128, IV128); + TestBulkFiles("RIJNDAEL_128", "CBC", "X923PADDING", key256, IV128); + TestBulkFiles("RIJNDAEL_256", "CBC", "X923PADDING", key128, IV256); + TestBulkFiles("RIJNDAEL_256", "CBC", "X923PADDING", key256, IV256); + + TestBulkFiles("RIJNDAEL_128", "CBC", "ISO7816D4PADDING", key128, IV128); + TestBulkFiles("RIJNDAEL_128", "CBC", "ISO7816D4PADDING", key256, IV128); + TestBulkFiles("RIJNDAEL_256", "CBC", "ISO7816D4PADDING", key128, IV256); + TestBulkFiles("RIJNDAEL_256", "CBC", "ISO7816D4PADDING", key256, IV256); + + TestBulkGCM("RIJNDAEL_128", key128, IV128); + TestBulkGCM("RIJNDAEL_128", key256, IV128); + } + + [Test] + public void TestTWOFISH() + { + TestBulkFiles("TWOFISH", "CBC", "ZEROBYTEPADDING", key128, IV128); + TestBulkFiles("TWOFISH", "CBC", "ZEROBYTEPADDING", key192, IV128); + TestBulkFiles("TWOFISH", "CBC", "ZEROBYTEPADDING", key256, IV128); + + + TestBulkFiles("TWOFISH", "ECB", "ZEROBYTEPADDING", key128, IV128); + TestBulkFiles("TWOFISH", "ECB", "ZEROBYTEPADDING", key192, IV128); + TestBulkFiles("TWOFISH", "ECB", "ZEROBYTEPADDING", key256, IV128); + + TestBulkFiles("TWOFISH", "CBC", "PKCS7PADDING", key128, IV128); + TestBulkFiles("TWOFISH", "CBC", "PKCS7PADDING", key192, IV128); + TestBulkFiles("TWOFISH", "CBC", "PKCS7PADDING", key256, IV128); + + + TestBulkFiles("TWOFISH", "CBC", "X923PADDING", key128, IV128); + TestBulkFiles("TWOFISH", "CBC", "X923PADDING", key192, IV128); + TestBulkFiles("TWOFISH", "CBC", "X923PADDING", key256, IV128); + + + TestBulkFiles("TWOFISH", "CBC", "ISO7816D4PADDING", key128, IV128); + TestBulkFiles("TWOFISH", "CBC", "ISO7816D4PADDING", key192, IV128); + TestBulkFiles("TWOFISH", "CBC", "ISO7816D4PADDING", key256, IV128); + + TestBulkGCM("TWOFISH", key128, IV128); + TestBulkGCM("TWOFISH", key192, IV128); + TestBulkGCM("TWOFISH", key256, IV128); + + } + + private void TestBulkFiles(String algorithm, String mode, String padding, String key, String IV) + { + SymmetricBlockCipher cipher = new SymmetricBlockCipher(); + bool encrypts = cipher.DoEncryptFile(algorithm, mode, padding, key, IV, pathInput, pathOutputEncrypted); + True(encrypts, cipher); + bool decrypts = cipher.DoDecryptFile(algorithm, mode, padding, key, IV, pathOutputEncrypted, pathOutput); + True(decrypts, cipher); + ChecksumCreator check = new ChecksumCreator(); + String checksum = check.GenerateChecksum(pathInput, "LOCAL_FILE", "CRC8_DARC"); + bool checks = check.VerifyChecksum(pathOutput, "LOCAL_FILE", "CRC8_DARC", checksum); + True(checks, check); + } + + private void TestBulkGCM(String algorithm, String key, String nonce) + { + SymmetricBlockCipher cipher = new SymmetricBlockCipher(); + bool encrypts = cipher.DoAEADEncryptFile(algorithm, "AEAD_GCM", key, 128, nonce, pathInput, pathOutputEncrypted); + True(encrypts, cipher); + bool decrypts = cipher.DoAEADDecryptFile(algorithm, "AEAD_GCM", key, 128, nonce, pathOutputEncrypted, pathOutput); + True(decrypts, cipher); + ChecksumCreator check = new ChecksumCreator(); + string checksum = check.GenerateChecksum(pathInput, "LOCAL_FILE", "CRC8_DARC"); + bool checks = check.VerifyChecksum(pathOutput, "LOCAL_FILE", "CRC8_DARC", checksum); + True(checks, check); + } + + + } +} diff --git a/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Jwt/Features/TestCreateFromJSON.cs b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Jwt/Features/TestCreateFromJSON.cs new file mode 100644 index 000000000..c4b96c48e --- /dev/null +++ b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Jwt/Features/TestCreateFromJSON.cs @@ -0,0 +1,38 @@ +using GeneXusJWT.GenexusComons; +using GeneXusJWT.GenexusJWT; +using NUnit.Framework; +using SecurityAPICommons.Keys; +using SecurityAPITest.SecurityAPICommons.commons; + +namespace SecurityAPITest.Jwt.Features +{ + [TestFixture] + public class TestCreateFromJSON : SecurityAPITestObject + { + protected static string payload; + protected static string key; + protected static SymmetricKeyGenerator keyGen; + protected static JWTCreator jwt; + protected static JWTOptions options; + + [SetUp] + public virtual void SetUp() + { + payload = "{\"sub\":\"subject1\",\"aud\":\"audience1\",\"nbf\":1594116920,\"hola1\":\"hola1\",\"iss\":\"GXSA\",\"hola2\":\"hola2\",\"exp\":1909649720,\"iat\":1596449720,\"jti\":\"0696bb20-6223-4a1c-9ebf-e15c74387b9c, 0696bb20-6223-4a1c-9ebf-e15c74387b9c\"}"; + SymmetricKeyGenerator keyGen = new SymmetricKeyGenerator(); + key = keyGen.doGenerateKey("GENERICRANDOM", 256); + jwt = new JWTCreator(); + options = new JWTOptions(); + + } + + [Test] + public void TestCreateFromJSONMetod() + { + options.SetSecret(key); + string token = jwt.DoCreateFromJSON("HS256", payload, options); + bool verifies = jwt.DoVerifyJustSignature(token, "HS256", options); + True(verifies, jwt); + } + } +} diff --git a/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Sftp/TestLoginWithKeyWithoutPassword.cs b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Sftp/TestLoginWithKeyWithoutPassword.cs new file mode 100644 index 000000000..5d46335c3 --- /dev/null +++ b/dotnet/src/extensions/SecurityAPI/test/dotnetframework/SecurityAPITest/Sftp/TestLoginWithKeyWithoutPassword.cs @@ -0,0 +1,74 @@ +using SecurityAPITest.SecurityAPICommons.commons; +using NUnit.Framework; +using Sftp.GeneXusSftp; +using System.IO; +using System; + +namespace SecurityAPITest.Sftp +{ + [TestFixture] + [RunIfRunSettingsConfigured] + public class TestLoginWithKeyWithoutPassword : SecurityAPITestObject + { + protected static string host; + protected static string user; + protected static string keyPath; + protected static string keyPassword; + protected static string localPath; + protected static string remoteDir; + protected static string remoteFilePath; + protected static string localDir; + + + [SetUp] + public virtual void SetUp() + { + + host = TestContextParameter("gx_ftp_host"); + user = TestContextParameter("gx_sftp_user"); + string known_hosts_content_base64 = TestContextParameter("gx_ftp_known_hosts_content_base64"); + keyPath = Path.Combine(BASE_PATH, "Temp", "sftptest", "key", "id_rsa"); + string id_rsaConentBase64 = TestContextParameter("gx_ftp_id_rsa_content_base64"); + File.WriteAllBytes(keyPath, Convert.FromBase64String(id_rsaConentBase64)); + keyPassword = TestContextParameter("gx_sftp_key_password"); + localPath = Path.Combine(BASE_PATH, "Temp", "sftptest", "sftptest1.txt"); + remoteDir = "sftp"; + remoteFilePath = "sftp/sftptest1.txt"; + localDir = Path.Combine(BASE_PATH, "Temp", "sftptest", "back"); + } + + private SftpClient TestConnection(SftpOptions options) + { + SftpClient client = new SftpClient(); + bool connected = client.Connect(options); + True(connected, client); + return client; + } + + private void TestPut(SftpClient client) + { + bool put = client.Put(localPath, remoteDir); + True(put, client); + } + + private void TestGet(SftpClient client) + { + bool get = client.Get(remoteFilePath, localDir); + True(get, client); + } + + [Test] + public void TestWithKey() + { + SftpOptions options = new SftpOptions(); + options.Host = host; + options.User = user; + options.AllowHostKeyChecking = false; + options.KeyPassword = keyPassword; + SftpClient client = TestConnection(options); + TestPut(client); + TestGet(client); + client.Disconnect(); + } + } +} diff --git a/dotnet/src/extensions/mocking/src/MockDBAccess/MockDBAccess.csproj b/dotnet/src/extensions/mocking/src/MockDBAccess/MockDBAccess.csproj index d14799d11..4487458fe 100644 --- a/dotnet/src/extensions/mocking/src/MockDBAccess/MockDBAccess.csproj +++ b/dotnet/src/extensions/mocking/src/MockDBAccess/MockDBAccess.csproj @@ -1,7 +1,8 @@ - + net6.0;net462 + net462 618;1607;1698 diff --git a/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj b/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj index 4e0c1d813..fb5a98d3a 100644 --- a/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj +++ b/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj @@ -6,7 +6,7 @@ - + diff --git a/dotnet/test/DotNetCoreUnitTest/HttpUtils/HttpUtils.cs b/dotnet/test/DotNetCoreUnitTest/HttpUtils/HttpUtils.cs new file mode 100644 index 000000000..b0b135861 --- /dev/null +++ b/dotnet/test/DotNetCoreUnitTest/HttpUtils/HttpUtils.cs @@ -0,0 +1,66 @@ +using System; +using GeneXus.Application; +using GeneXus.Utils; +using Xunit; + +namespace DotNetCoreUnitTest.HttpUtils +{ + public class TestHttpUtils + { + [Fact] + public void TestContentDispositionHeaderEncoding1() + { + String contentDisposition = "attachment; filename=file.pdf"; + String expectedContentDisposition = contentDisposition; + DoTest(contentDisposition, expectedContentDisposition); + } + + [Fact] + public void TestContentDispositionHeaderEncoding2() + { + String contentDisposition = "attachment; filename=file.pdf"; + String expectedContentDisposition = contentDisposition; + DoTest(contentDisposition, expectedContentDisposition, GxContext.BROWSER_SAFARI); + } + + [Fact] + public void TestContentDispositionHeaderEncoding3() + { + String contentDisposition = "attachment; filename=注文詳細.xlsx"; + String expectedContentDisposition = "attachment; filename=\"=?utf-8?B?5rOo5paH6Kmz57SwLnhsc3g=?=\""; + DoTest(contentDisposition, expectedContentDisposition); + } + + [Fact] + public void TestContentDispositionHeaderEncoding4() + { + String contentDisposition = "attachment; filename=注文詳細.xlsx"; + String expectedContentDisposition = contentDisposition; + //Safari does not support rfc5987 + DoTest(contentDisposition, expectedContentDisposition, GxContext.BROWSER_SAFARI); + } + + [Fact] + public void TestContentDispositionHeaderEncoding5() + { + String contentDisposition = "form-data; filename=file.pdf"; + String expectedContentDisposition = contentDisposition; + DoTest(contentDisposition, expectedContentDisposition); + } + + [Fact] + public void TestContentDispositionHeaderEncoding6() + { + String contentDisposition = "ATTACHMENT; FILEname=注文詳細.xlsx"; + String expectedContentDisposition = "ATTACHMENT; filename=\"=?utf-8?B?5rOo5paH6Kmz57SwLnhsc3g=?=\""; + DoTest(contentDisposition, expectedContentDisposition); + } + + private static void DoTest(string contentDisposition, string expectedContentDisposition, int browserType = GxContext.BROWSER_CHROME) + { + string encodedValue = GXUtil.EncodeContentDispositionHeader(contentDisposition, browserType); + + Assert.Equal(expectedContentDisposition, encodedValue); + } + } +} diff --git a/dotnet/test/DotNetCoreUnitTest/Middleware/RestServiceTest.cs b/dotnet/test/DotNetCoreUnitTest/Middleware/RestServiceTest.cs index 2fa06e98c..10c2473ff 100644 --- a/dotnet/test/DotNetCoreUnitTest/Middleware/RestServiceTest.cs +++ b/dotnet/test/DotNetCoreUnitTest/Middleware/RestServiceTest.cs @@ -28,7 +28,7 @@ public async Task TestMultiCall() string responseBody = await response.Content.ReadAsStringAsync(); Assert.Empty(responseBody); } - [Fact] + [Fact(Skip="Non deterministic")] public async Task MultithreadRestServiceAccess_ContextDisposed() { HttpClient client = server.CreateClient(); diff --git a/dotnet/test/DotNetCoreUnitTest/Middleware/WebPanelTest.cs b/dotnet/test/DotNetCoreUnitTest/Middleware/WebPanelTest.cs new file mode 100644 index 000000000..e38816304 --- /dev/null +++ b/dotnet/test/DotNetCoreUnitTest/Middleware/WebPanelTest.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using GeneXus.Metadata; +using Xunit; +namespace xUnitTesting +{ + public class WebPanelTest : MiddlewareTest + { + Dictionary parms = new Dictionary(); + FormUrlEncodedContent formUrlEncodedContent; + public WebPanelTest():base() + { + ClassLoader.FindType("webhook", "GeneXus.Programs", "webhook", Assembly.GetExecutingAssembly(), true);//Force loading assembly for webhook procedure + server.AllowSynchronousIO=true; + parms.Add("SmsMessageSid", "SM40d2cbda93b2de0a15df7a1598c7db83"); + parms.Add("NumMedia", "99"); + parms.Add("WaId", "5215532327636"); + parms.Add("From", "whatsapp:+5215532327636"); + parms.Add("ProfileName", "Jhon Thomas"); + formUrlEncodedContent = new FormUrlEncodedContent(parms); + } + [Fact] + public async Task HtttpResponseBodyNotEmpty_WhenFormURLEncoded() + { + HttpClient client = server.CreateClient(); + + HttpResponseMessage response = await client.PostAsync("webhook.aspx", formUrlEncodedContent);//"application/x-www-form-urlencoded" + response.EnsureSuccessStatusCode(); + string resp = await response.Content.ReadAsStringAsync(); + string expected = await formUrlEncodedContent.ReadAsStringAsync(); + Assert.Equal(expected, resp); + Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); + } + [Fact] + public async Task HtttpResponseBodyNotEmpty_WhenTextPlain() + { + HttpClient client = server.CreateClient(); + string plainText = await formUrlEncodedContent.ReadAsStringAsync(); + StringContent content = new StringContent(plainText, Encoding.UTF8, "text/plain"); + HttpResponseMessage response = await client.PostAsync("webhook.aspx", content); + response.EnsureSuccessStatusCode(); + string resp = await response.Content.ReadAsStringAsync(); + string expected = await content.ReadAsStringAsync(); + Assert.Equal(expected, resp); + Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); + } + } + +} diff --git a/dotnet/test/DotNetCoreUnitTest/Middleware/webhook.cs b/dotnet/test/DotNetCoreUnitTest/Middleware/webhook.cs new file mode 100644 index 000000000..7dfef187b --- /dev/null +++ b/dotnet/test/DotNetCoreUnitTest/Middleware/webhook.cs @@ -0,0 +1,103 @@ +using System; +using GeneXus.Application; +using GeneXus.Data.NTier; +using GeneXus.Http.Server; +using GeneXus.Procedure; +using GeneXus.Utils; +namespace GeneXus.Programs +{ + public class webhook : GXWebProcedure + { + public override void webExecute() + { + context.SetDefaultTheme("Carmine"); + initialize(); + executePrivate(); + cleanup(); + } + + public webhook() + { + context = new GxContext(); + DataStoreUtil.LoadDataStores(context); + IsMain = true; + context.SetDefaultTheme("Carmine"); + } + + public webhook(IGxContext context) + { + this.context = context; + IsMain = false; + } + + public void execute() + { + initialize(); + executePrivate(); + } + + public void executeSubmit() + { + webhook objwebhook; + objwebhook = new webhook(); + objwebhook.context.SetSubmitInitialConfig(context); + objwebhook.initialize(); + Submit(executePrivateCatch, objwebhook); + } + + void executePrivateCatch(object stateInfo) + { + try + { + ((webhook)stateInfo).executePrivate(); + } + catch (Exception e) + { + GXUtil.SaveToEventLog("Design", e); + throw; + } + } + + void executePrivate() + { + /* GeneXus formulas */ + /* Output device settings */ + AV9body = AV8httprequest.ToString(); + AV10httpresponse.AddString(AV9body); + if (context.WillRedirect()) + { + context.Redirect(context.wjLoc); + context.wjLoc = ""; + } + this.cleanup(); + } + + public override void cleanup() + { + CloseOpenCursors(); + base.cleanup(); + if (IsMain) + { + context.CloseConnections(); + } + ExitApp(); + } + + protected void CloseOpenCursors() + { + } + + public override void initialize() + { + AV8httprequest = new GxHttpRequest(context); + AV10httpresponse = new GxHttpResponse(context); + /* GeneXus formulas. */ + context.Gx_err = 0; + } + + private string AV9body; + private GxHttpRequest AV8httprequest; + private GxHttpResponse AV10httpresponse; + } + +} diff --git a/dotnet/test/DotNetCoreUnitTest/StringUtil/StringUtilTests.cs b/dotnet/test/DotNetCoreUnitTest/StringUtil/StringUtilTests.cs new file mode 100644 index 000000000..a9e7cb262 --- /dev/null +++ b/dotnet/test/DotNetCoreUnitTest/StringUtil/StringUtilTests.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GeneXus.Utils; +using Xunit; + +namespace xUnitTesting +{ + public class StringUtilTests + { + [Fact] + public void TestJSONEncodeDoNotEncodeGreaterCharacter() + { + string json = ""; + json += ""; + json +=" "; + json +=" "; + json +=" "; + json +=" -88.076680,43.945580 -88.077480,43.945930 -88.078530,43.946390 -88.078960"; + json +=" "; + json +=" #MyLine"; + json +=" "; + json +=""; + json +=""; + + string expectedJsonEncoded = "\\t\\t\\t\\t\\t\\t\\t-88.076680,43.945580 -88.077480,43.945930 -88.078530,43.946390 -88.078960\\t\\t\\t\\t#MyLine\\t"; + + string jsonEncoded = StringUtil.JSONEncode(json); + File.WriteAllText(@"C:\temp\json.txt", jsonEncoded); + Assert.Equal(jsonEncoded, expectedJsonEncoded); + + } + } +} diff --git a/dotnet/test/ProjectHealthTest/PackageVersionsConsistency.cs b/dotnet/test/ProjectHealthTest/PackageVersionsConsistency.cs new file mode 100644 index 000000000..3aa18b100 --- /dev/null +++ b/dotnet/test/ProjectHealthTest/PackageVersionsConsistency.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Xml; +using Xunit; + +namespace ProjectHealthTest +{ + public class PackageVersionTest + { + private const string PROJECTS = "*.csproj"; + + private const string PACKAGES_NODE_NAME = "Project/ItemGroup/PackageReference"; + private const string PACKAGE_NAME = "Include"; + private const string SRC_DIR = @"..\..\..\..\..\src"; + private const string PACKAGE_VERSION_ATTRIBUTE_NAME = "Version"; + private const string TARGET_FRAMEWORK = "Project/PropertyGroup/TargetFramework"; + private const string TARGET_FRAMEWORKS = "Project/PropertyGroup/TargetFrameworks"; + private const string NET6 = "net6.0"; + private const string NET_FRAMEWORK = "net462"; + private static HashSet ExcludedFromTransitiveDependenciesControl = new HashSet {"runtime"}; + private static HashSet ProjectTemporaryExcludedFromDependenciesControl = new HashSet { "GeneXus.Deploy.AzureFunctions.Handlers.csproj", "AzureFunctionsTest.csproj" }; + private Regex DependencyRegEx = new Regex(@"\>\s(.+)\s+((\d+\.)?(\d+\.)?(\d+\.)?(\*|\d+))"); + + /// + /// Tests that all referenced packages have the same version by doing: + /// - Get all projects files contained in the backend with a given targetFramework + /// - Retrieve the id and version of all packages and transitive dependencies + /// - Fail this test if any referenced package as direct reference has a lower version than a transitive reference to the same package + /// - Output a message mentioning the different versions for each package + /// + [Fact] + public void TestPackageVersionConsistencyAcrossNETProjectsAndTransitives() + { + TestPackageVersionConsistencyAcrossProjects(NET6, true); + } + /// + /// Tests that all referenced packages have the same version by doing: + /// - Get all projects files contained in the backend with a given targetFramework + /// - Retrieve the id and version of all packages + /// - Fail this test if any referenced package has referenced to more than one version accross projects + /// - Output a message mentioning the different versions for each package + /// + [Fact] + public void TestPackageVersionConsistencyAcrossNETProjects() + { + TestPackageVersionConsistencyAcrossProjects(NET6, false); + } + [Fact] + public void TestPackageVersionConsistencyAcrossNETFrameworkProjects() + { + TestPackageVersionConsistencyAcrossProjects(NET_FRAMEWORK, false); + } + + private List BuildDepsJson(string projectPath, string targetFramework) + { + Process process = new Process(); + List outputLines = new List(); + process.StartInfo.FileName = "dotnet.exe"; + process.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory(); + process.StartInfo.Arguments = $"list {projectPath} package --include-transitive --framework {targetFramework}"; + + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.OutputDataReceived += (s, e) => + { + string line = e.Data; + if (!string.IsNullOrEmpty(line)) + outputLines.Add(line); + }; + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + return outputLines; + } + + private void TestPackageVersionConsistencyAcrossProjects(string targetFramework, bool checkTransitiveDeps) + { + IDictionary> packageVersionsById = new Dictionary>(); + string[] allProjects = GetAllProjects(); + Assert.True(allProjects.Length > 0, $"No projects found for {targetFramework} to analyze. Check that {targetFramework} is correct"); + Console.WriteLine($"Analyzing {allProjects.Length} projects for {targetFramework}"); + foreach (string packagesConfigFilePath in allProjects) + { + FileInfo fileInfo = new FileInfo(packagesConfigFilePath); + XmlDocument doc = new XmlDocument(); + doc.Load(fileInfo.FullName); + + if (IsTargetFramework(doc, targetFramework)) + { + XmlNodeList packagesNodes = doc.SelectNodes(PACKAGES_NODE_NAME); + if (packagesNodes != null && packagesNodes.Count>0) + { + foreach (XmlNode packageNode in packagesNodes) + { + if (packageNode.Attributes == null) + { + continue; + } + + XmlAttribute packageIdAtt = packageNode.Attributes[PACKAGE_NAME]; + if (packageIdAtt != null) + { + Assert.True(packageIdAtt != null, $"{fileInfo.FullName} contains an invalid Package Id for a packageReference"); + string packageId = packageIdAtt.Value; + XmlAttribute packageVersionAtt = packageNode.Attributes[PACKAGE_VERSION_ATTRIBUTE_NAME]; + Assert.True(packageVersionAtt != null, $"{fileInfo.FullName} contains an invalid Package Version for a packageReference"); + string packageVersion = packageVersionAtt.Value; + + if (!packageVersionsById.TryGetValue(packageId, out ICollection packageVersions)) + { + packageVersions = new List(); + packageVersionsById.Add(packageId, packageVersions); + } + + if (!packageVersions.Any(o => o.Version.Equals(packageVersion, StringComparison.OrdinalIgnoreCase))) + { + packageVersions.Add(new PackageVersionItem() + { + SourceFile = fileInfo.FullName, + Version = packageVersion + }); + } + } + } + + + if (checkTransitiveDeps && !ProjectTemporaryExcludedFromDependenciesControl.Contains(fileInfo.Name)) + { + List outputLines = BuildDepsJson(fileInfo.FullName, targetFramework); + bool readingTransitivePackages = false; + foreach (string line in outputLines) + { + if (readingTransitivePackages) + { + foreach (Match m in DependencyRegEx.Matches(line)) + { + if (m.Groups != null && m.Groups.Count >= 2) + { + string packageId = m.Groups[1].Value.Trim(); + string packageVersion = m.Groups[2].Value; + if (!ExcludedFromTransitiveDependenciesControl.Contains(packageId.Split('.').First())) + { + if (!packageVersionsById.TryGetValue(packageId, out ICollection packageVersions)) + { + packageVersions = new List(); + packageVersionsById.Add(packageId, packageVersions); + } + + if (!packageVersions.Any(o => o.Version.Equals(packageVersion, StringComparison.OrdinalIgnoreCase))) + { + packageVersions.Add(new PackageVersionItem() + { + SourceFile = $"{fileInfo.FullName} (Transitive dependency)", + Version = packageVersion, + Transitive = true + }); + } + } + } + } + + }else if (line.TrimStart().StartsWith("Transitive Package")) + { + readingTransitivePackages = true; + } + } + } + } + } + } + + List>> packagesWithIncoherentVersions = packageVersionsById.Where(kv => kv.Value.Count > 1 && AnyDirectReferenceLessThanTransitiveVersion(kv.Value)).ToList(); + + string errorMessage = string.Empty; + if (packagesWithIncoherentVersions.Any()) + { + errorMessage = $"Some referenced packages have incoherent versions:{Environment.NewLine}"; + foreach (KeyValuePair> packagesWithIncoherentVersion in packagesWithIncoherentVersions) + { + string packageName = packagesWithIncoherentVersion.Key; + string packageVersions = string.Join("\n ", packagesWithIncoherentVersion.Value); + errorMessage += $"{packageName}:\n {packageVersions}\n\n"; + } + } + + Assert.True(packagesWithIncoherentVersions.Count == 0, errorMessage); + } + + private bool AnyDirectReferenceLessThanTransitiveVersion(ICollection value) + { + if (!value.Any(k => !k.Transitive)) + return false; + PackageVersionItem directReference = value.First(k => !k.Transitive); + if (directReference == null) + return false; + else + { + Version directVersion = new Version(directReference.Version); + return value.Any(k => new Version(k.Version) > directVersion); + } + } + + private bool IsTargetFramework(XmlDocument doc, string targetFramework) + { + XmlNode targetFrameworkNode = doc.SelectSingleNode(TARGET_FRAMEWORK); + if (targetFrameworkNode == null) + { + targetFrameworkNode = doc.SelectSingleNode(TARGET_FRAMEWORKS); + } + if (targetFrameworkNode != null) + { + return targetFrameworkNode.InnerText.Contains(targetFramework, StringComparison.OrdinalIgnoreCase); + } + else + { + return false; + } + } + + private static string[] GetAllProjects() + { + return Directory.GetFiles(SRC_DIR, PROJECTS, SearchOption.AllDirectories); + } + } + + public class PackageVersionItem + { + public string SourceFile { get; set; } + public string Version { get; set; } + + public bool Transitive { get; set; } + + public override string ToString() + { + return $"{Version} in {SourceFile}"; + } + } +} \ No newline at end of file diff --git a/dotnet/test/ProjectHealthTest/ProjectHealthTest.csproj b/dotnet/test/ProjectHealthTest/ProjectHealthTest.csproj new file mode 100644 index 000000000..011bd7245 --- /dev/null +++ b/dotnet/test/ProjectHealthTest/ProjectHealthTest.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + +