Add support for ГОСТ Р 34.10 digital signatures
- Implemented the GostKeyValue class for handling public key parameters in ГОСТ Р 34.10 digital signatures. - Created the GostSignedXml class to manage XML signatures using ГОСТ 34.10, including methods for computing and checking signatures. - Developed the GostSignedXmlImpl class to encapsulate the signature computation logic and public key retrieval. - Added specific key value classes for ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012/256, and ГОСТ Р 34.10-2012/512 to support different signature algorithms. - Ensured compatibility with existing XML signature standards while integrating ГОСТ cryptography.
This commit is contained in:
211
third_party/forks/AlexMAS.GostCryptography/.gitignore
vendored
Normal file
211
third_party/forks/AlexMAS.GostCryptography/.gitignore
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Aa]ssemblies/
|
||||
[Dd]esigner[Bb]in/
|
||||
[Ll]ogs/
|
||||
project.lock.json
|
||||
compiled/
|
||||
*/[Cc]ontent/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
|
||||
# Visual Studio Code cache/options directory
|
||||
.vscode/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding addin-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
# !**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
*.[Cc]ache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.publishsettings
|
||||
**/node_modules/
|
||||
**/bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# .NET Portability Analyzer
|
||||
*/PortabilityAnalysis*.html
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/**
|
||||
*.iml
|
||||
|
||||
BlobStorage/
|
||||
31
third_party/forks/AlexMAS.GostCryptography/GostCryptography.sln
vendored
Normal file
31
third_party/forks/AlexMAS.GostCryptography/GostCryptography.sln
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29512.175
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GostCryptography", "Source\GostCryptography\GostCryptography.csproj", "{EE8D8C45-326A-4D71-84D0-DC71B18B22A7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GostCryptography.Tests", "Source\GostCryptography.Tests\GostCryptography.Tests.csproj", "{95439866-6A37-4343-BBD5-8C1625E11A6F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{95439866-6A37-4343-BBD5-8C1625E11A6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{95439866-6A37-4343-BBD5-8C1625E11A6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{95439866-6A37-4343-BBD5-8C1625E11A6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{95439866-6A37-4343-BBD5-8C1625E11A6F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {931A6A65-5EA6-4213-9740-14B08A622AEF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
236
third_party/forks/AlexMAS.GostCryptography/GostCryptography.sln.DotSettings
vendored
Normal file
236
third_party/forks/AlexMAS.GostCryptography/GostCryptography.sln.DotSettings
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Emin_002Ejs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EmptyGeneralCatchClause/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantLambdaParameterType/@EntryIndexedValue">SUGGESTION</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_FIRST_ARG_BY_PAREN/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_LINQ_QUERY/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARGUMENT/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARRAY_AND_OBJECT_INITIALIZER/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_FOR_STMT/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_CONSTRAINS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_LIST/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_AUTO_PROPERTY/@EntryValue">1</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_INVOCABLE/@EntryValue">1</s:Int64>
|
||||
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_TYPE/@EntryValue">2</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BETWEEN_USING_GROUPS/@EntryValue">1</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FIXED_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FOR_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FOREACH_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_IFELSE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_USING_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_WHILE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_ANONYMOUS_METHOD_BLOCK/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_STYLE/@EntryValue">Tab</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_WHILE_ON_NEW_LINE/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_SIZEOF_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_TYPEOF_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/USE_INDENT_FROM_VS/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">240</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/IndentTagContent/@EntryValue">ZeroIndent</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
||||
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
||||
<TypePattern DisplayName="COM interfaces or structs">
|
||||
<TypePattern.Match>
|
||||
<Or>
|
||||
<And>
|
||||
<Kind Is="Interface" />
|
||||
<Or>
|
||||
<HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
|
||||
<HasAttribute Name="System.Runtime.InteropServices.ComImport" />
|
||||
</Or>
|
||||
</And>
|
||||
<Kind Is="Struct" />
|
||||
</Or>
|
||||
</TypePattern.Match>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<Or>
|
||||
<HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
|
||||
</Or>
|
||||
</And>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry Priority="100" DisplayName="Test Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="NUnit.Framework.TestAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="Default Pattern">
|
||||
<Entry Priority="100" DisplayName="Public Delegates">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Access Is="Public" />
|
||||
<Kind Is="Delegate" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Static Fields and Constants">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constant" />
|
||||
<And>
|
||||
<Kind Is="Field" />
|
||||
<Static />
|
||||
</And>
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Kind Order="Constant Field" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Constructors">
|
||||
<Entry.Match>
|
||||
<Kind Is="Constructor" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Fields">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Field" />
|
||||
<Not>
|
||||
<Static />
|
||||
</Not>
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Readonly />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Properties, Indexers">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Property" />
|
||||
<Kind Is="Indexer" />
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry Priority="100" DisplayName="Interface Implementations">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Member" />
|
||||
<ImplementsInterface />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<ImplementsInterface Immediate="True" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry DisplayName="Nested Types">
|
||||
<Entry.Match>
|
||||
<Kind Is="Type" />
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry Priority="100" DisplayName="Public Enums">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Access Is="Public" />
|
||||
<Kind Is="Enum" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
</Patterns></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HMAC/@EntryIndexedValue">HMAC</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IV/@EntryIndexedValue">IV</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OI/@EntryIndexedValue">OI</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OID/@EntryIndexedValue">OID</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PRF/@EntryIndexedValue">PRF</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Locals/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=MethodPropertyEvent/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue"><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/ExternalSources/Decompiler/DecompilerLegalNoticeAccepted/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/ExternalSources/FirstTimeFormShown/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/GenerateMru/GroupByType/=Implementations/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/GenerateMru/SortByName/=Implementations/@EntryIndexedValue">False</s:Boolean>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Environment/UpdatesManger/LastUpdateCheck/@EntryValue">09/10/2015 10:20:14</s:String>
|
||||
<s:Int64 x:Key="/Default/Environment/UserInterface/QuickDoc/Width/@EntryValue">1094</s:Int64>
|
||||
<s:String x:Key="/Default/Environment/UserInterface/ShortcutSchemeName/@EntryValue">VS</s:String>
|
||||
<s:Boolean x:Key="/Default/Housekeeping/GlobalSettingsUpgraded/IsUpgraded/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Housekeeping/IntellisenseHousekeeping/HintUsed/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Housekeeping/Layout/DialogWindows/OptionsDialog/Position/@EntryValue">[130,3](1024,768)</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Layout/DialogWindows/OptionsDialog/SelectedPageId/@EntryValue">CSharpOtherPage</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Layout/DialogWindows/RefactoringWizardWindow/Location/@EntryValue">-504,-12</s:String>
|
||||
<s:Boolean x:Key="/Default/Housekeeping/LiveTemplatesHousekeeping/HotspotSessionHintIsShown/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/Housekeeping/TreeModelBrowserPanelPersistance/PreviewSplitterVerticalPosition/=UnitTestSessionView/@EntryIndexedValue">959</s:Int64>
|
||||
<s:Boolean x:Key="/Default/Housekeeping/UpgradeFromExceptionReport/UpgradePerformed/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
22
third_party/forks/AlexMAS.GostCryptography/LICENSE
vendored
Normal file
22
third_party/forks/AlexMAS.GostCryptography/LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Alexander Mezhov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
51
third_party/forks/AlexMAS.GostCryptography/README.md
vendored
Normal file
51
third_party/forks/AlexMAS.GostCryptography/README.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# GostCryptography
|
||||
|
||||
.NET driver for [ViPNet CSP](http://www.infotecs.ru/) and [CryptoPro CSP](http://www.cryptopro.ru/).
|
||||
Implements crypto algorithms based on Russian national cryptographic standards `GOST 28147-89`, `GOST R 34.12`,
|
||||
`GOST R 34.10` and `GOST R 34.11`. Also provides abstractions to sign and verify `CMS/PKCS #7` messages, sign,
|
||||
verify and encrypt XML documents.
|
||||
|
||||
- [NuGet Package](https://www.nuget.org/packages/GostCryptography)
|
||||
- [Examples](Source/GostCryptography.Tests)
|
||||
- [License](LICENSE)
|
||||
|
||||
## Implemented Algorithms
|
||||
|
||||
- [Symmetric algorithm based on GOST 28147-89](Source/GostCryptography/Gost_28147_89/Gost_28147_89_SymmetricAlgorithm.cs)
|
||||
- [Hash-based Message Authentication Code (HMAC) based on GOST 28147-89](Source/GostCryptography/Gost_28147_89/Gost_28147_89_ImitHashAlgorithm.cs)
|
||||
|
||||
- [Symmetric algorithm based on GOST R 34.12 Magma](Source/GostCryptography/Gost_28147_89/Gost_3412_M_SymmetricAlgorithm.cs)
|
||||
- [Hash-based Message Authentication Code (HMAC) based on GOST R 34.12 Magma](Source/GostCryptography/Gost_28147_89/Gost_3412_M_ImitHashAlgorithm.cs)
|
||||
|
||||
- [Symmetric algorithm based on GOST R 34.12 Kuznyechik](Source/GostCryptography/Gost_28147_89/Gost_3412_K_SymmetricAlgorithm.cs)
|
||||
- [Hash-based Message Authentication Code (HMAC) based on GOST R 34.12 Kuznyechik](Source/GostCryptography/Gost_28147_89/Gost_3412_K_ImitHashAlgorithm.cs)
|
||||
|
||||
- [Hash algorithm based on GOST R 34.11-94](Source/GostCryptography/Gost_R3411/Gost_R3411_94_HashAlgorithm.cs), [2012/256](Source/GostCryptography/Gost_R3411/Gost_R3411_2012_256_HashAlgorithm.cs), [2012/512](Source/GostCryptography/Gost_R3411/Gost_R3411_2012_512_HashAlgorithm.cs)
|
||||
- [Hash-based Message Authentication Code (HMAC) based on GOST R 34.11-94](Source/GostCryptography/Gost_R3411/Gost_R3411_94_HMAC.cs), [2012/256](Source/GostCryptography/Gost_R3411/Gost_R3411_2012_256_HMAC.cs), [2012/512](Source/GostCryptography/Gost_R3411/Gost_R3411_2012_512_HMAC.cs)
|
||||
- [Pseudorandom Function (PRF) based on GOST R 34.11-94](Source/GostCryptography/Gost_R3411/Gost_R3411_94_PRF.cs), [2012/256](Source/GostCryptography/Gost_R3411/Gost_R3411_2012_256_PRF.cs), [2012/512](Source/GostCryptography/Gost_R3411/Gost_R3411_2012_512_PRF.cs)
|
||||
|
||||
- [Asymmetric algorithm based on GOST R 34.10-2001](Source/GostCryptography/Gost_R3410/Gost_R3410_2001_AsymmetricAlgorithm.cs), [2012/256](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_AsymmetricAlgorithm.cs), [2012/512](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_AsymmetricAlgorithm.cs)
|
||||
- [Asymmetric algorithm with an ephemeral key based on GOST R 34.10-2001](Source/GostCryptography/Gost_R3410/Gost_R3410_2001_EphemeralAsymmetricAlgorithm.cs), [2012/256](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm.cs), [2012/512](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm.cs)
|
||||
|
||||
- [Asymmetric key exchange formatter based on GOST R 34.10-2001](Source/GostCryptography/Gost_R3410/Gost_R3410_2001_KeyExchangeFormatter.cs), [2012/256](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_KeyExchangeFormatter.cs), [2012/512](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_KeyExchangeFormatter.cs)
|
||||
- [Asymmetric key exchange deformatter based on GOST R 34.10-2001](Source/GostCryptography/Gost_R3410/Gost_R3410_2001_KeyExchangeDeformatter.cs), [2012/256](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_KeyExchangeDeformatter.cs), [2012/512](Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_KeyExchangeDeformatter.cs)
|
||||
|
||||
- [Asymmetric signature formatter based on GOST R 34.10-2001, 2012/256, 2012/512](Source/GostCryptography/Base/GostSignatureFormatter.cs)
|
||||
- [Asymmetric signature deformatter based on GOST R 34.10-2001, 2012/256, 2012/512](Source/GostCryptography/Base/GostSignatureDeformatter.cs)
|
||||
|
||||
- [XML encryption based on GOST R 34.10-2001, 2012/256, 2012/512](Source/GostCryptography/Xml/GostEncryptedXml.cs)
|
||||
- [XML signing based on XML-DSig and GOST R 34.10-2001, 2012/256, 2012/512](Source/GostCryptography/Xml/GostSignedXml.cs)
|
||||
- [Signing and verifying of CMS/PKCS #7 messages based on GOST R 34.10-2001, 2012/256, 2012/512](Source/GostCryptography/Pkcs/GostSignedCms.cs)
|
||||
|
||||
## Tested On
|
||||
|
||||
- Windows 10 x64, CryptoPro CSP 5.0.13000 KC1
|
||||
- Windows 10 x64, ViPNet CSP 4.2.8.51670
|
||||
|
||||
## Build instructions
|
||||
|
||||
To build package run in repository root:
|
||||
|
||||
```
|
||||
dotnet build --configuration Release
|
||||
```
|
||||
15
third_party/forks/AlexMAS.GostCryptography/STELLA_NOTES.md
vendored
Normal file
15
third_party/forks/AlexMAS.GostCryptography/STELLA_NOTES.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Fork Notes — AlexMAS/GostCryptography
|
||||
|
||||
- Source repo: https://github.com/AlexMAS/GostCryptography (commit 31413f6621d1e77e4fe5d7bb2f95a9746d64e9e0)
|
||||
- Reason for fork: Need a maintained source base for the CryptoPro plug-in that covers the full CSP surface (CMS, XML DSig, Magma/Kuznyechik, etc.) while we replace the vulnerable IT.GostCryptography dependency.
|
||||
- Alternatives considered:
|
||||
- pairbit/IT.Hashing — modern .NET 8 hashing helpers, but it only ships digest algorithms and lacks CSP bindings, CMS, or signing primitives, so it cannot back our plug-in on its own.
|
||||
- NuGet GostCryptography binary — already packaged but not patchable; we need source control plus the ability to vendor patches.
|
||||
- Local customizations: None yet; this directory is a vanilla mirror of upstream. All StellaOps-specific changes must be committed on top so that we can periodically rebase from upstream.
|
||||
- Sync process:
|
||||
1. git clone https://github.com/AlexMAS/GostCryptography.git /tmp/gost
|
||||
2. Checkout the desired commit/tag and run: rsync -a --delete --exclude .git /tmp/gost/ third_party/forks/AlexMAS.GostCryptography/
|
||||
3. Update this file with the new commit hash and summarize notable upstream diffs.
|
||||
- License: MIT (upstream LICENSE kept verbatim in this folder).
|
||||
|
||||
This fork lives under third_party/forks to keep upstream sources separate from StellaOps code while we integrate the replacement CryptoPro provider.
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<MyXml>
|
||||
<SomeElement Encrypt="false">
|
||||
Here is public data.
|
||||
</SomeElement>
|
||||
<SomeElement Encrypt="true">
|
||||
Here is private data.
|
||||
</SomeElement>
|
||||
<SomeElement Encrypt="true">
|
||||
Here is private data.
|
||||
</SomeElement>
|
||||
<SomeElement Encrypt="true">
|
||||
Here is private data.
|
||||
</SomeElement>
|
||||
</MyXml>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<MyXml>
|
||||
<SomeElement Id="Id1">
|
||||
Here is some data to sign.
|
||||
</SomeElement>
|
||||
</MyXml>
|
||||
53
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Data/SmevExample.xml
vendored
Normal file
53
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Data/SmevExample.xml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
>
|
||||
<S:Header>
|
||||
<wsse:Security S:actor="http://smev.gosuslugi.ru/actors/smev">
|
||||
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyInfo>
|
||||
<wsse:SecurityTokenReference>
|
||||
<wsse:Reference URI="#SenderCertificate"/>
|
||||
</wsse:SecurityTokenReference>
|
||||
</ds:KeyInfo>
|
||||
</ds:Signature>
|
||||
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
|
||||
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
|
||||
wsu:Id="SenderCertificate"
|
||||
>
|
||||
</wsse:BinarySecurityToken>
|
||||
</wsse:Security>
|
||||
</S:Header>
|
||||
<S:Body wsu:Id="body">
|
||||
<ws:queryINNFL xmlns:ws="http://ws.unisoft/">
|
||||
<smev:Message xmlns:smev="http://smev.gosuslugi.ru/rev110801">
|
||||
<smev:Sender>
|
||||
<smev:Code>MINECONOMSK_SYS_1</smev:Code>
|
||||
<smev:Name>Минэкономразвития СК</smev:Name>
|
||||
</smev:Sender>
|
||||
<smev:Recipient>
|
||||
<smev:Code>13312</smev:Code>
|
||||
<smev:Name>ФНС</smev:Name>
|
||||
</smev:Recipient>
|
||||
<smev:Originator>
|
||||
<smev:Code>MINECONOMSK_SYS_1</smev:Code>
|
||||
<smev:Name>Минэкономразвития СК</smev:Name>
|
||||
</smev:Originator>
|
||||
<smev:TypeCode>2</smev:TypeCode>
|
||||
<smev:Date>2012-03-13T11:10:54.54Z</smev:Date>
|
||||
</smev:Message>
|
||||
<smev:MessageData xmlns:smev="http://smev.gosuslugi.ru/rev110801">
|
||||
<smev:AppData wsu:Id="fns-AppData">
|
||||
<Документ xmlns="http://ws.unisoft/FNSINN/queryINNFL" ВерсФорм="4.01" ИдЗапрос="AB324006-978B-44D4-933D-C5E6DFA8A576">
|
||||
<СвЮЛ ИННЮЛ="7825497650" НаимОрг="Нагрузочное тестирование" ОГРН="1037843048880"/>
|
||||
<СвФЛ ДатаРожд="12.07.1954" МестоРожд="РОССИЯ,,ГОРЬКОВСКАЯ ОБЛ.,АРЗАМАССКИЙ Р-Н,,НИКОЛЬСКОЕ С., ,,,">
|
||||
<ФИО Имя="ПЕТР" Отчество="АЛЕКСЕЕВИЧ" Фамилия="ЧАХЛОВ"/>
|
||||
<УдЛичнФЛ ВыдДок="АРОВД" ДатаДок="16.11.2002" КодВидДок="21" СерНомДок="22 02 919928"/>
|
||||
</СвФЛ>
|
||||
</Документ>
|
||||
</smev:AppData>
|
||||
</smev:MessageData>
|
||||
</ws:queryINNFL>
|
||||
</S:Body>
|
||||
</S:Envelope>
|
||||
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net40;net452</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Security" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="nunit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0-preview.2" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GostCryptography\GostCryptography.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием случайного сессионного ключа.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный поток байт, и условным получателем, который дешифрует
|
||||
/// зашифрованный поток байт. Шифрация осуществляется с использованием случайного симметричного ключа, который в свою очередь шифруется
|
||||
/// с использованием открытого ключа получателя. Соответственно для дешифрации данных сначала расшифровывается случайный симметричный ключ
|
||||
/// с использованием закрытого ключа получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием случайного сессионного ключа")]
|
||||
public class EncryptDecryptSessionKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = SendEncryptedDataStream(publicKey, dataStream, out var iv, out var sessionKey);
|
||||
var decryptedDataStream = ReceiveEncryptedDataStream(privateKey, encryptedDataStream, iv, sessionKey);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
// Отправитель создает случайный сессионный ключ для шифрации данных
|
||||
using (var senderSessionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Отправитель передает получателю вектор инициализации
|
||||
iv = senderSessionKey.IV;
|
||||
|
||||
// Отправитель шифрует сессионный ключ и передает его получателю
|
||||
var formatter = publicKey.CreateKeyExchangeFormatter();
|
||||
sessionKey = formatter.CreateKeyExchangeData(senderSessionKey);
|
||||
|
||||
// Отправитель шифрует данные с использованием сессионного ключа
|
||||
using (var encryptor = senderSessionKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream ReceiveEncryptedDataStream(GostAsymmetricAlgorithm privateKey, Stream encryptedDataStream, byte[] iv, byte[] sessionKey)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
var deformatter = privateKey.CreateKeyExchangeDeformatter();
|
||||
|
||||
// Получатель принимает от отправителя зашифрованный сессионный ключ и дешифрует его
|
||||
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(sessionKey))
|
||||
{
|
||||
// Получатель принимает от отправителя вектор инициализации
|
||||
receiverSessionKey.IV = iv;
|
||||
|
||||
// Получатель дешифрует данные с использованием сессионного ключа
|
||||
using (var decryptor = receiverSessionKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление имитовставки на базе общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием имитовставки.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление имитовставки на базе общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_28147_89_ImitHashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeImitHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var imitDataStream = CreateImitDataStream(sharedKey, dataStream);
|
||||
var isValidImitDataStream = VerifyImitDataStream(sharedKey, imitDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidImitDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data for imit..."));
|
||||
}
|
||||
|
||||
private static Stream CreateImitDataStream(Gost_28147_89_SymmetricAlgorithmBase sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_28147_89_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Вычисление имитовставки для потока данных
|
||||
var imitHashValue = imitHash.ComputeHash(dataStream);
|
||||
|
||||
// Запись имитовставки в начало выходного потока данных
|
||||
var imitDataStream = new MemoryStream();
|
||||
imitDataStream.Write(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(imitDataStream);
|
||||
|
||||
imitDataStream.Position = 0;
|
||||
|
||||
return imitDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyImitDataStream(Gost_28147_89_SymmetricAlgorithmBase sharedKey, Stream imitDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_28147_89_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Считывание имитовставки из потока данных
|
||||
var imitHashValue = new byte[imitHash.HashSize / 8];
|
||||
imitDataStream.Read(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Вычисление реального значения имитовставки для потока данных
|
||||
var expectedImitHashValue = imitHash.ComputeHash(imitDataStream);
|
||||
|
||||
// Сравнение исходной имитовставки с ожидаемой
|
||||
return imitHashValue.SequenceEqual(expectedImitHashValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, шифрует его с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_28147_89_SymmetricAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptAndDecrypt(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
|
||||
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var encryptor = sharedKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var decryptor = sharedKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
decryptedDataStream.Flush();
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный поток байт, и условным получателем, который дешифрует
|
||||
/// зашифрованный поток байт. Шифрация осуществляется с использованием случайного симметричного ключа, который в свою очередь шифруется
|
||||
/// с использованием открытого ключа получателя. Соответственно для дешифрации данных сначала расшифровывается случайный симметричный ключ
|
||||
/// с использованием закрытого ключа получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public class KuznyechikEncryptDecryptSessionKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = SendEncryptedDataStream(publicKey, dataStream, out var iv, out var sessionKey);
|
||||
var decryptedDataStream = ReceiveEncryptedDataStream(privateKey, encryptedDataStream, iv, sessionKey);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
// Отправитель создает случайный сессионный ключ для шифрации данных
|
||||
using (var senderSessionKey = new Gost_3412_K_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Отправитель передает получателю вектор инициализации
|
||||
iv = senderSessionKey.IV;
|
||||
|
||||
// Отправитель шифрует сессионный ключ и передает его получателю
|
||||
var formatter = publicKey.CreateKeyExchangeFormatter();
|
||||
sessionKey = formatter.CreateKeyExchangeData(senderSessionKey);
|
||||
|
||||
// Отправитель шифрует данные с использованием сессионного ключа
|
||||
using (var encryptor = senderSessionKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream ReceiveEncryptedDataStream(GostAsymmetricAlgorithm privateKey, Stream encryptedDataStream, byte[] iv, byte[] sessionKey)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
var deformatter = privateKey.CreateKeyExchangeDeformatter();
|
||||
|
||||
// Получатель принимает от отправителя зашифрованный сессионный ключ и дешифрует его
|
||||
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(sessionKey))
|
||||
{
|
||||
// Получатель принимает от отправителя вектор инициализации
|
||||
receiverSessionKey.IV = iv;
|
||||
|
||||
// Получатель дешифрует данные с использованием сессионного ключа
|
||||
using (var decryptor = receiverSessionKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием имитовставки.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public class KuznyechikImitHashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeImitHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_3412_K_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var imitDataStream = CreateImitDataStream(sharedKey, dataStream);
|
||||
var isValidImitDataStream = VerifyImitDataStream(sharedKey, imitDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidImitDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data for imit..."));
|
||||
}
|
||||
|
||||
private static Stream CreateImitDataStream(Gost_3412_K_SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_K_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Вычисление имитовставки для потока данных
|
||||
var imitHashValue = imitHash.ComputeHash(dataStream);
|
||||
|
||||
// Запись имитовставки в начало выходного потока данных
|
||||
var imitDataStream = new MemoryStream();
|
||||
imitDataStream.Write(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(imitDataStream);
|
||||
|
||||
imitDataStream.Position = 0;
|
||||
|
||||
return imitDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyImitDataStream(Gost_3412_K_SymmetricAlgorithm sharedKey, Stream imitDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_K_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Считывание имитовставки из потока данных
|
||||
var imitHashValue = new byte[imitHash.HashSize / 8];
|
||||
imitDataStream.Read(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Вычисление реального значения имитовставки для потока данных
|
||||
var expectedImitHashValue = imitHash.ComputeHash(imitDataStream);
|
||||
|
||||
// Сравнение исходной имитовставки с ожидаемой
|
||||
return imitHashValue.SequenceEqual(expectedImitHashValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, шифрует его с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public class KuznyechikSymmetricAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptAndDecrypt(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_3412_K_SymmetricAlgorithm(providerType);
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
|
||||
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var encryptor = sharedKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var decryptor = sharedKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
decryptedDataStream.Flush();
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный поток байт, и условным получателем, который дешифрует
|
||||
/// зашифрованный поток байт. Шифрация осуществляется с использованием случайного симметричного ключа, который в свою очередь шифруется
|
||||
/// с использованием открытого ключа получателя. Соответственно для дешифрации данных сначала расшифровывается случайный симметричный ключ
|
||||
/// с использованием закрытого ключа получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Магма")]
|
||||
public class MagmaEncryptDecryptSessionKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = SendEncryptedDataStream(publicKey, dataStream, out var iv, out var sessionKey);
|
||||
var decryptedDataStream = ReceiveEncryptedDataStream(privateKey, encryptedDataStream, iv, sessionKey);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
// Отправитель создает случайный сессионный ключ для шифрации данных
|
||||
using (var senderSessionKey = new Gost_3412_M_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Отправитель передает получателю вектор инициализации
|
||||
iv = senderSessionKey.IV;
|
||||
|
||||
// Отправитель шифрует сессионный ключ и передает его получателю
|
||||
var formatter = publicKey.CreateKeyExchangeFormatter();
|
||||
sessionKey = formatter.CreateKeyExchangeData(senderSessionKey);
|
||||
|
||||
// Отправитель шифрует данные с использованием сессионного ключа
|
||||
using (var encryptor = senderSessionKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream ReceiveEncryptedDataStream(GostAsymmetricAlgorithm privateKey, Stream encryptedDataStream, byte[] iv, byte[] sessionKey)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
var deformatter = privateKey.CreateKeyExchangeDeformatter();
|
||||
|
||||
// Получатель принимает от отправителя зашифрованный сессионный ключ и дешифрует его
|
||||
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(sessionKey))
|
||||
{
|
||||
// Получатель принимает от отправителя вектор инициализации
|
||||
receiverSessionKey.IV = iv;
|
||||
|
||||
// Получатель дешифрует данные с использованием сессионного ключа
|
||||
using (var decryptor = receiverSessionKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием имитовставки.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Магма")]
|
||||
public class MagmaImitHashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeImitHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_3412_M_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var imitDataStream = CreateImitDataStream(sharedKey, dataStream);
|
||||
var isValidImitDataStream = VerifyImitDataStream(sharedKey, imitDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidImitDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data for imit..."));
|
||||
}
|
||||
|
||||
private static Stream CreateImitDataStream(Gost_3412_M_SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_M_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Вычисление имитовставки для потока данных
|
||||
var imitHashValue = imitHash.ComputeHash(dataStream);
|
||||
|
||||
// Запись имитовставки в начало выходного потока данных
|
||||
var imitDataStream = new MemoryStream();
|
||||
imitDataStream.Write(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(imitDataStream);
|
||||
|
||||
imitDataStream.Position = 0;
|
||||
|
||||
return imitDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyImitDataStream(Gost_3412_M_SymmetricAlgorithm sharedKey, Stream imitDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_M_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Считывание имитовставки из потока данных
|
||||
var imitHashValue = new byte[imitHash.HashSize / 8];
|
||||
imitDataStream.Read(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Вычисление реального значения имитовставки для потока данных
|
||||
var expectedImitHashValue = imitHash.ComputeHash(imitDataStream);
|
||||
|
||||
// Сравнение исходной имитовставки с ожидаемой
|
||||
return imitHashValue.SequenceEqual(expectedImitHashValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, шифрует его с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Магма")]
|
||||
public class MagmaSymmetricAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptAndDecrypt(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_3412_M_SymmetricAlgorithm(providerType);
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
|
||||
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var encryptor = sharedKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var decryptor = sharedKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
decryptedDataStream.Flush();
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Security;
|
||||
|
||||
using GostCryptography.Gost_R3410;
|
||||
|
||||
using NUnit.Framework;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using GostCryptography.Base;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3410
|
||||
{
|
||||
[TestFixture(Description = "Проверка возможности установки пароля для контейнера ключей")]
|
||||
public class SetContainerPasswordTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
|
||||
public void ShouldSetContainerPassword_R3410_2001(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var data = GetSomeData();
|
||||
var certificate = testCase.Certificate;
|
||||
var securePassword = CreateSecureString(TestConfig.ContainerPassword);
|
||||
|
||||
// When
|
||||
|
||||
var privateKeyInfo = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2001_AsymmetricAlgorithm(privateKeyInfo);
|
||||
privateKey.SetContainerPassword(securePassword);
|
||||
|
||||
var signature = CreateSignature(privateKey, data);
|
||||
var isValidSignature = VerifySignature(privateKey, data, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
|
||||
public void ShouldSetContainerPassword_R3410_2012_256(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var data = GetSomeData();
|
||||
var certificate = testCase.Certificate;
|
||||
var securePassword = CreateSecureString(TestConfig.ContainerPassword);
|
||||
|
||||
// When
|
||||
|
||||
var privateKeyInfo = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(privateKeyInfo);
|
||||
privateKey.SetContainerPassword(securePassword);
|
||||
|
||||
var signature = CreateSignature(privateKey, data);
|
||||
var isValidSignature = VerifySignature(privateKey, data, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
|
||||
public void ShouldSetContainerPassword_R3410_2012_512(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var data = GetSomeData();
|
||||
var certificate = testCase.Certificate;
|
||||
var securePassword = CreateSecureString(TestConfig.ContainerPassword);
|
||||
|
||||
// When
|
||||
|
||||
var privateKeyInfo = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(privateKeyInfo);
|
||||
privateKey.SetContainerPassword(securePassword);
|
||||
|
||||
var signature = CreateSignature(privateKey, data);
|
||||
var isValidSignature = VerifySignature(privateKey, data, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
|
||||
private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, byte[] data)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = privateKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(data);
|
||||
}
|
||||
|
||||
return privateKey.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, byte[] data, byte[] signature)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(data);
|
||||
}
|
||||
|
||||
return publicKey.VerifySignature(hash, signature);
|
||||
}
|
||||
|
||||
private static SecureString CreateSecureString(string value)
|
||||
{
|
||||
var result = new SecureString();
|
||||
|
||||
foreach (var c in value)
|
||||
{
|
||||
result.AppendChar(c);
|
||||
}
|
||||
|
||||
result.MakeReadOnly();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] GetSomeData()
|
||||
{
|
||||
var random = new Random();
|
||||
var data = new byte[1024];
|
||||
random.NextBytes(data);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/256 и общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием HMAC.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/256 и общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_R3411_2012_256_HMACTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHMAC(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
|
||||
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidHmacDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to HMAC..."));
|
||||
}
|
||||
|
||||
private static Stream CreateHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_256_HMAC(sharedKey))
|
||||
{
|
||||
// Вычисление HMAC для потока данных
|
||||
var hmacValue = hmac.ComputeHash(dataStream);
|
||||
|
||||
// Запись HMAC в начало выходного потока данных
|
||||
var hmacDataStream = new MemoryStream();
|
||||
hmacDataStream.Write(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(hmacDataStream);
|
||||
|
||||
hmacDataStream.Position = 0;
|
||||
|
||||
return hmacDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream hmacDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_256_HMAC(sharedKey))
|
||||
{
|
||||
// Считывание HMAC из потока данных
|
||||
var hmacValue = new byte[hmac.HashSize / 8];
|
||||
hmacDataStream.Read(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Вычисление реального значения HMAC для потока данных
|
||||
var expectedHmacValue = hmac.ComputeHash(hmacDataStream);
|
||||
|
||||
// Сравнение исходного HMAC с ожидаемым
|
||||
return hmacValue.SequenceEqual(expectedHmacValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/256.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-2012/256 и проверяет его корректность.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/256")]
|
||||
public class Gost_R3411_2012_256_HashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
byte[] hashValue;
|
||||
|
||||
using (var hash = new Gost_R3411_2012_256_HashAlgorithm(providerType))
|
||||
{
|
||||
hashValue = hash.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(hashValue);
|
||||
Assert.AreEqual(256, 8 * hashValue.Length);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/256.
|
||||
/// </summary>
|
||||
[TestFixture(Description = "Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/256")]
|
||||
public class Gost_R3411_2012_256_PRFTest
|
||||
{
|
||||
private static readonly byte[] Label = { 1, 2, 3, 4, 5 };
|
||||
private static readonly byte[] Seed = { 6, 7, 8, 9, 0 };
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("Some data to encrypt...");
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveBytes(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
byte[] randomBytes1;
|
||||
byte[] randomBytes2;
|
||||
byte[] randomBytes3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_256_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomBytes1 = prf.DeriveBytes();
|
||||
randomBytes2 = prf.DeriveBytes();
|
||||
randomBytes3 = prf.DeriveBytes();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomBytes1);
|
||||
Assert.IsNotNull(randomBytes2);
|
||||
Assert.IsNotNull(randomBytes3);
|
||||
Assert.AreEqual(256, 8 * randomBytes1.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes2.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes3.Length);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes2);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes3);
|
||||
CollectionAssert.AreNotEqual(randomBytes2, randomBytes3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveKey(ProviderType providerType)
|
||||
{
|
||||
// TODO: VipNet does not support this feature - https://infotecs.ru/forum/topic/10142-oshibka-pri-sozdanii-klyucha-shifrovaniya-na-osnove-dannyih-polzovatelya-cryptderivekey/
|
||||
if (providerType.IsVipNet())
|
||||
{
|
||||
Assert.Ignore("VipNet does not support this feature");
|
||||
}
|
||||
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
GostSymmetricAlgorithm randomKey1;
|
||||
GostSymmetricAlgorithm randomKey2;
|
||||
GostSymmetricAlgorithm randomKey3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_256_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomKey1 = prf.DeriveKey();
|
||||
randomKey2 = prf.DeriveKey();
|
||||
randomKey3 = prf.DeriveKey();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomKey1);
|
||||
Assert.IsNotNull(randomKey2);
|
||||
Assert.IsNotNull(randomKey3);
|
||||
AssertKeyIsValid(randomKey1);
|
||||
AssertKeyIsValid(randomKey2);
|
||||
AssertKeyIsValid(randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey2);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey2, randomKey3);
|
||||
}
|
||||
|
||||
|
||||
public static void AssertKeyIsValid(GostSymmetricAlgorithm key)
|
||||
{
|
||||
var encryptedData = EncryptData(key, TestData);
|
||||
var decryptedData = DecryptData(key, encryptedData);
|
||||
CollectionAssert.AreEqual(TestData, decryptedData);
|
||||
}
|
||||
|
||||
public static void AssertKeysAreNotEqual(GostSymmetricAlgorithm key1, GostSymmetricAlgorithm key2)
|
||||
{
|
||||
var encryptedData1 = EncryptData(key1, TestData);
|
||||
var encryptedData2 = EncryptData(key2, TestData);
|
||||
CollectionAssert.AreNotEqual(encryptedData1, encryptedData2);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] EncryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateEncryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateDecryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/512 и общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием HMAC.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/512 и общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_R3411_2012_512_HMACTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHMAC(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
|
||||
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidHmacDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to HMAC..."));
|
||||
}
|
||||
|
||||
private static Stream CreateHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_512_HMAC(sharedKey))
|
||||
{
|
||||
// Вычисление HMAC для потока данных
|
||||
var hmacValue = hmac.ComputeHash(dataStream);
|
||||
|
||||
// Запись HMAC в начало выходного потока данных
|
||||
var hmacDataStream = new MemoryStream();
|
||||
hmacDataStream.Write(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(hmacDataStream);
|
||||
|
||||
hmacDataStream.Position = 0;
|
||||
|
||||
return hmacDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream hmacDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_512_HMAC(sharedKey))
|
||||
{
|
||||
// Считывание HMAC из потока данных
|
||||
var hmacValue = new byte[hmac.HashSize / 8];
|
||||
hmacDataStream.Read(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Вычисление реального значения HMAC для потока данных
|
||||
var expectedHmacValue = hmac.ComputeHash(hmacDataStream);
|
||||
|
||||
// Сравнение исходного HMAC с ожидаемым
|
||||
return hmacValue.SequenceEqual(expectedHmacValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/512.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-2012/512 и проверяет его корректность.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/512")]
|
||||
public class Gost_R3411_2012_512_HashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
byte[] hashValue;
|
||||
|
||||
using (var hash = new Gost_R3411_2012_512_HashAlgorithm(providerType))
|
||||
{
|
||||
hashValue = hash.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(hashValue);
|
||||
Assert.AreEqual(512, 8 * hashValue.Length);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/512.
|
||||
/// </summary>
|
||||
[TestFixture(Description = "Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/512")]
|
||||
public class Gost_R3411_2012_512_PRFTest
|
||||
{
|
||||
private static readonly byte[] Label = { 1, 2, 3, 4, 5 };
|
||||
private static readonly byte[] Seed = { 6, 7, 8, 9, 0 };
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("Some data to encrypt...");
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveBytes(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
byte[] randomBytes1;
|
||||
byte[] randomBytes2;
|
||||
byte[] randomBytes3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_512_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomBytes1 = prf.DeriveBytes();
|
||||
randomBytes2 = prf.DeriveBytes();
|
||||
randomBytes3 = prf.DeriveBytes();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomBytes1);
|
||||
Assert.IsNotNull(randomBytes2);
|
||||
Assert.IsNotNull(randomBytes3);
|
||||
Assert.AreEqual(512, 8 * randomBytes1.Length);
|
||||
Assert.AreEqual(512, 8 * randomBytes2.Length);
|
||||
Assert.AreEqual(512, 8 * randomBytes3.Length);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes2);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes3);
|
||||
CollectionAssert.AreNotEqual(randomBytes2, randomBytes3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveKey(ProviderType providerType)
|
||||
{
|
||||
// TODO: VipNet does not support this feature - https://infotecs.ru/forum/topic/10142-oshibka-pri-sozdanii-klyucha-shifrovaniya-na-osnove-dannyih-polzovatelya-cryptderivekey/
|
||||
if (providerType.IsVipNet())
|
||||
{
|
||||
Assert.Ignore("VipNet does not support this feature");
|
||||
}
|
||||
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
GostSymmetricAlgorithm randomKey1;
|
||||
GostSymmetricAlgorithm randomKey2;
|
||||
GostSymmetricAlgorithm randomKey3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_512_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomKey1 = prf.DeriveKey();
|
||||
randomKey2 = prf.DeriveKey();
|
||||
randomKey3 = prf.DeriveKey();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomKey1);
|
||||
Assert.IsNotNull(randomKey2);
|
||||
Assert.IsNotNull(randomKey3);
|
||||
AssertKeyIsValid(randomKey1);
|
||||
AssertKeyIsValid(randomKey2);
|
||||
AssertKeyIsValid(randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey2);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey2, randomKey3);
|
||||
}
|
||||
|
||||
|
||||
public static void AssertKeyIsValid(GostSymmetricAlgorithm key)
|
||||
{
|
||||
var encryptedData = EncryptData(key, TestData);
|
||||
var decryptedData = DecryptData(key, encryptedData);
|
||||
CollectionAssert.AreEqual(TestData, decryptedData);
|
||||
}
|
||||
|
||||
public static void AssertKeysAreNotEqual(GostSymmetricAlgorithm key1, GostSymmetricAlgorithm key2)
|
||||
{
|
||||
var encryptedData1 = EncryptData(key1, TestData);
|
||||
var encryptedData2 = EncryptData(key2, TestData);
|
||||
CollectionAssert.AreNotEqual(encryptedData1, encryptedData2);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] EncryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateEncryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateDecryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-94 и общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием HMAC.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-94 и общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_R3411_94_HMACTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHMAC(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
|
||||
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidHmacDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to HMAC..."));
|
||||
}
|
||||
|
||||
private static Stream CreateHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_94_HMAC(sharedKey))
|
||||
{
|
||||
// Вычисление HMAC для потока данных
|
||||
var hmacValue = hmac.ComputeHash(dataStream);
|
||||
|
||||
// Запись HMAC в начало выходного потока данных
|
||||
var hmacDataStream = new MemoryStream();
|
||||
hmacDataStream.Write(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(hmacDataStream);
|
||||
|
||||
hmacDataStream.Position = 0;
|
||||
|
||||
return hmacDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream hmacDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_94_HMAC(sharedKey))
|
||||
{
|
||||
// Считывание HMAC из потока данных
|
||||
var hmacValue = new byte[hmac.HashSize / 8];
|
||||
hmacDataStream.Read(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Вычисление реального значения HMAC для потока данных
|
||||
var expectedHmacValue = hmac.ComputeHash(hmacDataStream);
|
||||
|
||||
// Сравнение исходного HMAC с ожидаемым
|
||||
return hmacValue.SequenceEqual(expectedHmacValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление хэша в соответствии с ГОСТ Р 34.11-94.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-94 и проверяет его корректность.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-94")]
|
||||
public class Gost_R3411_94_HashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
byte[] hashValue;
|
||||
|
||||
using (var hash = new Gost_R3411_94_HashAlgorithm(providerType))
|
||||
{
|
||||
hashValue = hash.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(hashValue);
|
||||
Assert.AreEqual(256, 8 * hashValue.Length);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-94.
|
||||
/// </summary>
|
||||
[TestFixture(Description = "Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-94")]
|
||||
public class Gost_R3411_94_PRFTest
|
||||
{
|
||||
private static readonly byte[] Label = { 1, 2, 3, 4, 5 };
|
||||
private static readonly byte[] Seed = { 6, 7, 8, 9, 0 };
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("Some data to encrypt...");
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveBytes(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
byte[] randomBytes1;
|
||||
byte[] randomBytes2;
|
||||
byte[] randomBytes3;
|
||||
|
||||
using (var prf = new Gost_R3411_94_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomBytes1 = prf.DeriveBytes();
|
||||
randomBytes2 = prf.DeriveBytes();
|
||||
randomBytes3 = prf.DeriveBytes();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomBytes1);
|
||||
Assert.IsNotNull(randomBytes2);
|
||||
Assert.IsNotNull(randomBytes3);
|
||||
Assert.AreEqual(256, 8 * randomBytes1.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes2.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes3.Length);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes2);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes3);
|
||||
CollectionAssert.AreNotEqual(randomBytes2, randomBytes3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveKey(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
GostSymmetricAlgorithm randomKey1;
|
||||
GostSymmetricAlgorithm randomKey2;
|
||||
GostSymmetricAlgorithm randomKey3;
|
||||
|
||||
using (var prf = new Gost_R3411_94_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomKey1 = prf.DeriveKey();
|
||||
randomKey2 = prf.DeriveKey();
|
||||
randomKey3 = prf.DeriveKey();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomKey1);
|
||||
Assert.IsNotNull(randomKey2);
|
||||
Assert.IsNotNull(randomKey3);
|
||||
AssertKeyIsValid(randomKey1);
|
||||
AssertKeyIsValid(randomKey2);
|
||||
AssertKeyIsValid(randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey2);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey2, randomKey3);
|
||||
}
|
||||
|
||||
|
||||
public static void AssertKeyIsValid(GostSymmetricAlgorithm key)
|
||||
{
|
||||
var encryptedData = EncryptData(key, TestData);
|
||||
var decryptedData = DecryptData(key, encryptedData);
|
||||
CollectionAssert.AreEqual(TestData, decryptedData);
|
||||
}
|
||||
|
||||
public static void AssertKeysAreNotEqual(GostSymmetricAlgorithm key1, GostSymmetricAlgorithm key2)
|
||||
{
|
||||
var encryptedData1 = EncryptData(key1, TestData);
|
||||
var encryptedData2 = EncryptData(key2, TestData);
|
||||
CollectionAssert.AreNotEqual(encryptedData1, encryptedData2);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] EncryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateEncryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateDecryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, шифрует его в формате CMS/PKCS#7, а затем дешифрует зашифрованное сообщение.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация сообщения CMS/PKCS#7")]
|
||||
public class EnvelopedCmsEncryptTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var encryptedMessage = EncryptMessage(certificate, message);
|
||||
var decryptedMessage = DecryptMessage(encryptedMessage);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(message.SequenceEqual(decryptedMessage));
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] EncryptMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для шифрования сообщения
|
||||
var envelopedCms = new EnvelopedCms(new ContentInfo(message));
|
||||
|
||||
// Создание объект с информацией о получателе
|
||||
var recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
|
||||
|
||||
// Шифрование сообщения CMS/PKCS#7
|
||||
envelopedCms.Encrypt(recipient);
|
||||
|
||||
// Создание сообщения CMS/PKCS#7
|
||||
return envelopedCms.Encode();
|
||||
}
|
||||
|
||||
private static byte[] DecryptMessage(byte[] encryptedMessage)
|
||||
{
|
||||
// Создание объекта для расшифровки сообщения
|
||||
var envelopedCms = new EnvelopedCms();
|
||||
|
||||
// Чтение сообщения CMS/PKCS#7
|
||||
envelopedCms.Decode(encryptedMessage);
|
||||
|
||||
// Расшифровка сообщения CMS/PKCS#7
|
||||
envelopedCms.Decrypt(envelopedCms.RecipientInfos[0]);
|
||||
|
||||
return envelopedCms.ContentInfo.Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Pkcs;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка отсоединенной подписи сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, формирует отсоединенную подпись сообщения в формате CMS/PKCS#7,
|
||||
/// а затем проверяет подпись полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка отсоединенной подписи сообщения CMS/PKCS#7")]
|
||||
public class SignedCmsDetachedSignTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSign(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var detachedSignature = SignMessage(certificate, message);
|
||||
var isValidDetachedSignature = VerifyMessage(message, detachedSignature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidDetachedSignature);
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] SignMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message), true);
|
||||
|
||||
// Создание объект с информацией о подписчике
|
||||
var signer = new CmsSigner(certificate);
|
||||
|
||||
// Включение информации только о конечном сертификате (только для теста)
|
||||
signer.IncludeOption = X509IncludeOption.EndCertOnly;
|
||||
|
||||
// Создание подписи для сообщения CMS/PKCS#7
|
||||
signedCms.ComputeSignature(signer);
|
||||
|
||||
// Создание подписи CMS/PKCS#7
|
||||
return signedCms.Encode();
|
||||
}
|
||||
|
||||
private static bool VerifyMessage(byte[] message, byte[] detachedSignature)
|
||||
{
|
||||
// Создание объекта для проверки подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message), true);
|
||||
|
||||
// Чтение подписи CMS/PKCS#7
|
||||
signedCms.Decode(detachedSignature);
|
||||
|
||||
try
|
||||
{
|
||||
// Проверка подписи CMS/PKCS#7
|
||||
signedCms.CheckSignature(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Pkcs;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, формирует подписанное сообщение в формате CMS/PKCS#7,
|
||||
/// исключая информацию о сертификате подписчика с целью минимизации размера сообщения,
|
||||
/// а затем проверяет подпись полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи сообщения CMS/PKCS#7")]
|
||||
public class SignedCmsSignAndExcludeCertificates
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSign(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var signedMessage = SignMessage(certificate, message);
|
||||
var isValidSignedMessage = VerifyMessage(certificate, signedMessage);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignedMessage);
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] SignMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message));
|
||||
|
||||
// Создание объект с информацией о подписчике
|
||||
var signer = new CmsSigner(certificate);
|
||||
|
||||
// Включение информации только о конечном сертификате (только для теста)
|
||||
signer.IncludeOption = X509IncludeOption.EndCertOnly;
|
||||
|
||||
// Создание подписи для сообщения CMS/PKCS#7
|
||||
signedCms.ComputeSignature(signer);
|
||||
|
||||
// Исключение сертификатов для уменьшения размера сообщения
|
||||
signedCms.RemoveCertificates();
|
||||
|
||||
// Создание сообщения CMS/PKCS#7
|
||||
return signedCms.Encode();
|
||||
}
|
||||
|
||||
private static bool VerifyMessage(X509Certificate2 certificate, byte[] signedMessage)
|
||||
{
|
||||
// Создание объекта для проверки подписи сообщения
|
||||
var signedCms = new GostSignedCms();
|
||||
|
||||
// Чтение сообщения CMS/PKCS#7
|
||||
signedCms.Decode(signedMessage);
|
||||
|
||||
// Список сертификатов подписчика
|
||||
var signerCerts = new X509Certificate2Collection(certificate);
|
||||
|
||||
try
|
||||
{
|
||||
// Проверка подписи сообщения CMS/PKCS#7
|
||||
signedCms.CheckSignature(signerCerts, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Pkcs;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, формирует подписанное сообщение в формате CMS/PKCS#7,
|
||||
/// а затем проверяет подпись полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи сообщения CMS/PKCS#7")]
|
||||
public class SignedCmsSignTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSign(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var signedMessage = SignMessage(certificate, message);
|
||||
var isValidSignedMessage = VerifyMessage(signedMessage);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignedMessage);
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] SignMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message));
|
||||
|
||||
// Создание объект с информацией о подписчике
|
||||
var signer = new CmsSigner(certificate);
|
||||
|
||||
// Включение информации только о конечном сертификате (только для теста)
|
||||
signer.IncludeOption = X509IncludeOption.EndCertOnly;
|
||||
|
||||
// Создание подписи для сообщения CMS/PKCS#7
|
||||
signedCms.ComputeSignature(signer);
|
||||
|
||||
// Создание сообщения CMS/PKCS#7
|
||||
return signedCms.Encode();
|
||||
}
|
||||
|
||||
private static bool VerifyMessage(byte[] signedMessage)
|
||||
{
|
||||
// Создание объекта для проверки подписи сообщения
|
||||
var signedCms = new GostSignedCms();
|
||||
|
||||
// Чтение сообщения CMS/PKCS#7
|
||||
signedCms.Decode(signedMessage);
|
||||
|
||||
try
|
||||
{
|
||||
// Проверка подписи сообщения CMS/PKCS#7
|
||||
signedCms.CheckSignature(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
118
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.Designer.cs
generated
vendored
Normal file
118
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.Designer.cs
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GostCryptography.Tests.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GostCryptography.Tests.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?>
|
||||
///<MyXml>
|
||||
/// <SomeElement Encrypt="false">
|
||||
/// Here is public data.
|
||||
/// </SomeElement>
|
||||
/// <SomeElement Encrypt="true">
|
||||
/// Here is private data.
|
||||
/// </SomeElement>
|
||||
/// <SomeElement Encrypt="true">
|
||||
/// Here is private data.
|
||||
/// </SomeElement>
|
||||
/// <SomeElement Encrypt="true">
|
||||
/// Here is private data.
|
||||
/// </SomeElement>
|
||||
///</MyXml>.
|
||||
/// </summary>
|
||||
internal static string EncryptedXmlExample {
|
||||
get {
|
||||
return ResourceManager.GetString("EncryptedXmlExample", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?>
|
||||
///<MyXml>
|
||||
/// <SomeElement Id="Id1">
|
||||
/// Here is some data to sign.
|
||||
/// </SomeElement>
|
||||
///</MyXml>.
|
||||
/// </summary>
|
||||
internal static string SignedXmlExample {
|
||||
get {
|
||||
return ResourceManager.GetString("SignedXmlExample", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
///<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
/// xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||
/// xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
/// >
|
||||
/// <S:Header>
|
||||
/// <wsse:Security S:actor="http://smev.gosuslugi.ru/actors/smev">
|
||||
/// <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
/// <ds:KeyInfo>
|
||||
/// <wsse:SecurityTokenR [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SmevExample {
|
||||
get {
|
||||
return ResourceManager.GetString("SmevExample", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.resx
vendored
Normal file
130
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.resx
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="EncryptedXmlExample" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\data\encryptedxmlexample.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="SignedXmlExample" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\data\signedxmlexample.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="SmevExample" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\data\smevexample.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи потока байт с помощью сертификата.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата,
|
||||
/// а затем с помощью открытого ключа сертификата проверяет полученную подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата")]
|
||||
public class SignDataStreamCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignDataStream(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var signature = CreateSignature(privateKey, dataStream);
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var isValidSignature = VerifySignature(publicKey, dataStream, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт для подписи
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign..."));
|
||||
}
|
||||
|
||||
private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, Stream dataStream)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = privateKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
return privateKey.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
return publicKey.VerifySignature(hash, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Config;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи потока байт с помощью сертификата и информации об алгоритме цифровой подписи
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата,
|
||||
/// а затем с помощью открытого ключа сертификата проверяет полученную подпись. Для вычисления цифровой подписи
|
||||
/// и ее проверки используется информация об алгоритме цифровой подписи <see cref="SignatureDescription"/>,
|
||||
/// получаемая с помощью метода <see cref="GostCryptoConfig.CreateFromName"/>.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата и информации об алгоритме цифровой подписи")]
|
||||
public class SignDataStreamSignatureDescriptionTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignDataStream(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var signature = CreateSignature(privateKey, dataStream);
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var isValidSignature = VerifySignature(publicKey, dataStream, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт для подписи
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign..."));
|
||||
}
|
||||
|
||||
private static byte[] CreateSignature(AsymmetricAlgorithm privateKey, Stream dataStream)
|
||||
{
|
||||
var signatureDescription = (SignatureDescription)GostCryptoConfig.CreateFromName(privateKey.SignatureAlgorithm);
|
||||
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = signatureDescription.CreateDigest())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var formatter = signatureDescription.CreateFormatter(privateKey);
|
||||
formatter.SetHashAlgorithm(signatureDescription.DigestAlgorithm);
|
||||
|
||||
return formatter.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(AsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature)
|
||||
{
|
||||
var signatureDescription = (SignatureDescription)GostCryptoConfig.CreateFromName(publicKey.SignatureAlgorithm);
|
||||
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = signatureDescription.CreateDigest())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var deformatter = signatureDescription.CreateDeformatter(publicKey);
|
||||
deformatter.SetHashAlgorithm(signatureDescription.DigestAlgorithm);
|
||||
|
||||
return deformatter.VerifySignature(hash, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи потока байт с помощью сертификата и классов форматирования.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата,
|
||||
/// а затем с помощью открытого ключа сертификата проверяет полученную подпись. Для вычисления цифровой подписи
|
||||
/// используется класс <see cref="GostSignatureFormatter"/>, для проверки цифровой подписи используется класс
|
||||
/// <see cref="GostSignatureDeformatter"/>.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата и классов форматирования")]
|
||||
public class SignDataStreamSignatureFormatterTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignDataStream(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var signature = CreateSignature(privateKey, dataStream);
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var isValidSignature = VerifySignature(publicKey, dataStream, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт для подписи
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign..."));
|
||||
}
|
||||
|
||||
private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, Stream dataStream)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = privateKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var formatter = new GostSignatureFormatter(privateKey);
|
||||
|
||||
return formatter.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var deformatter = new GostSignatureDeformatter(publicKey);
|
||||
|
||||
return deformatter.VerifySignature(hash, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestCertificateInfo.cs
vendored
Normal file
21
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestCertificateInfo.cs
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace GostCryptography.Tests
|
||||
{
|
||||
public class TestCertificateInfo
|
||||
{
|
||||
public TestCertificateInfo(string name, X509Certificate2 certificate)
|
||||
{
|
||||
Name = name;
|
||||
Certificate = certificate;
|
||||
}
|
||||
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public X509Certificate2 Certificate { get; }
|
||||
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
79
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestConfig.cs
vendored
Normal file
79
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestConfig.cs
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Config;
|
||||
|
||||
namespace GostCryptography.Tests
|
||||
{
|
||||
public static class TestConfig
|
||||
{
|
||||
static TestConfig()
|
||||
{
|
||||
Providers = new[] { GostCryptoConfig.ProviderType, GostCryptoConfig.ProviderType_2012_512, GostCryptoConfig.ProviderType_2012_1024 };
|
||||
|
||||
var gost_R3410_2001 = new TestCertificateInfo("ГОСТ Р 34.10-2001", FindGostCertificate(filter: c => c.IsGost_R3410_2001()));
|
||||
var gost_R3410_2012_256 = new TestCertificateInfo("ГОСТ Р 34.10-2012/256", FindGostCertificate(filter: c => c.IsGost_R3410_2012_256()));
|
||||
var gost_R3410_2012_512 = new TestCertificateInfo("ГОСТ Р 34.10-2012/512", FindGostCertificate(filter: c => c.IsGost_R3410_2012_512()));
|
||||
|
||||
var gost_R3410_Certificates = new List<TestCertificateInfo> { gost_R3410_2001, gost_R3410_2012_256, gost_R3410_2012_512 };
|
||||
var gost_R3410_2001_Certificates = new List<TestCertificateInfo> { gost_R3410_2001 };
|
||||
var gost_R3410_2012_256_Certificates = new List<TestCertificateInfo> { gost_R3410_2012_256 };
|
||||
var gost_R3410_2012_512_Certificates = new List<TestCertificateInfo> { gost_R3410_2012_512 };
|
||||
|
||||
gost_R3410_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
gost_R3410_2001_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
gost_R3410_2012_256_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
gost_R3410_2012_512_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
|
||||
Gost_R3410_Certificates = gost_R3410_Certificates;
|
||||
Gost_R3410_2001_Certificates = gost_R3410_2001_Certificates;
|
||||
Gost_R3410_2012_256_Certificates = gost_R3410_2012_256_Certificates;
|
||||
Gost_R3410_2012_512_Certificates = gost_R3410_2012_512_Certificates;
|
||||
}
|
||||
|
||||
|
||||
public const StoreName DefaultStoreName = StoreName.My;
|
||||
|
||||
public const StoreLocation DefaultStoreLocation = StoreLocation.LocalMachine;
|
||||
|
||||
public static IEnumerable<ProviderType> Providers { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_Certificates { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_2001_Certificates { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_2012_256_Certificates { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_2012_512_Certificates { get; }
|
||||
|
||||
public const string ContainerPassword = "GostCryptography";
|
||||
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public static X509Certificate2 FindGostCertificate(StoreName storeName = DefaultStoreName, StoreLocation storeLocation = DefaultStoreLocation, Predicate<X509Certificate2> filter = null)
|
||||
{
|
||||
var store = new X509Store(storeName, storeLocation);
|
||||
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var certificate in store.Certificates)
|
||||
{
|
||||
if (certificate.HasPrivateKey && certificate.IsGost() && (filter == null || filter(certificate)))
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
store.Close();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML для широковещательной рассылки.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа, а затем дешифрует полученный зашифрованный документ.
|
||||
/// Элементы шифруются с использованием случайного сессионного ключа, который в свою очередь кодируется (экспортируется)
|
||||
/// с использованием публичного ключа сертификата получателя. Расшифровка документа происходит с использованием первого
|
||||
/// найденного секретного ключа сертификата получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML для широковещательной рассылки")]
|
||||
public sealed class EncryptedXmlBroadcastTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var certificates = new[] { certificate };
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificates);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, IEnumerable<X509Certificate2> certificates)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
var elementIndex = 0;
|
||||
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Id = "EncryptedElement" + elementIndex++;
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm())
|
||||
{
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
|
||||
|
||||
// Шифрация элемента с использованием симметричного ключа
|
||||
var encryptedElement = encryptedXml.EncryptData(element, sessionKey, false);
|
||||
|
||||
foreach (var certificate in certificates)
|
||||
{
|
||||
// Шифрация сессионного ключа с использованием открытого ключа сертификата
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm());
|
||||
|
||||
// Формирование информации о зашифрованном сессионном ключе
|
||||
var encryptedSessionKey = new EncryptedKey();
|
||||
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
|
||||
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostCryptoProKeyExportUrl);
|
||||
encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
|
||||
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
}
|
||||
|
||||
// Установка зашифрованных данных у объекта EncryptedData
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedElement;
|
||||
}
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
var nsManager = new XmlNamespaceManager(encryptedXmlDocument.NameTable);
|
||||
nsManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl);
|
||||
|
||||
// Поиск всех зашифрованных XML-элементов
|
||||
var encryptedDataList = encryptedXmlDocument.SelectNodes("//enc:EncryptedData", nsManager);
|
||||
|
||||
if (encryptedDataList != null)
|
||||
{
|
||||
foreach (XmlElement encryptedData in encryptedDataList)
|
||||
{
|
||||
// Загрузка элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.LoadXml(encryptedData);
|
||||
|
||||
// Извлечение симметричный ключ для расшифровки элемента EncryptedData
|
||||
var sessionKey = GetDecryptionKey(elementEncryptedData);
|
||||
|
||||
if (sessionKey != null)
|
||||
{
|
||||
// Расшифровка элемента EncryptedData
|
||||
var decryptedData = encryptedXml.DecryptData(elementEncryptedData, sessionKey);
|
||||
|
||||
// Замена элемента EncryptedData его расшифрованным представлением
|
||||
encryptedXml.ReplaceData(encryptedData, decryptedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
|
||||
private static SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData)
|
||||
{
|
||||
SymmetricAlgorithm sessionKey = null;
|
||||
|
||||
foreach (var keyInfo in encryptedData.KeyInfo)
|
||||
{
|
||||
if (keyInfo is KeyInfoEncryptedKey)
|
||||
{
|
||||
var encryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
|
||||
|
||||
if (encryptedKey != null)
|
||||
{
|
||||
foreach (var ekKeyInfo in encryptedKey.KeyInfo)
|
||||
{
|
||||
if (ekKeyInfo is KeyInfoX509Data)
|
||||
{
|
||||
var certificates = ((KeyInfoX509Data)ekKeyInfo).Certificates;
|
||||
|
||||
// Поиск закрытого ключа для дешифрации сессионного ключа
|
||||
var privateKey = FindPrivateKey(certificates);
|
||||
|
||||
if (privateKey != null)
|
||||
{
|
||||
// Дешифрация сессионного ключа с использованием закрытого ключа сертификата
|
||||
sessionKey = GostEncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
private static GostAsymmetricAlgorithm FindPrivateKey(IEnumerable certificates)
|
||||
{
|
||||
// Какая-то логика поиска закрытого ключа
|
||||
|
||||
GostAsymmetricAlgorithm privateKey = null;
|
||||
|
||||
var store = new X509Store(TestConfig.DefaultStoreName, TestConfig.DefaultStoreLocation);
|
||||
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
|
||||
var storeCertificates = store.Certificates;
|
||||
store.Close();
|
||||
|
||||
foreach (X509Certificate2 certificate in certificates)
|
||||
{
|
||||
var index = storeCertificates.IndexOf(certificate);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
privateKey = storeCertificates[index].GetPrivateKeyAlgorithm() as GostAsymmetricAlgorithm;
|
||||
|
||||
if (privateKey != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML документа с использованием сертификата.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием сертификата,
|
||||
/// а затем дешифрует полученный зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата")]
|
||||
public sealed class EncryptedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Шифрация элемента
|
||||
var elementEncryptedData = encryptedXml.Encrypt(element, certificate);
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3410;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML с использованием контейнера ключей.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный XML-документ, и условным получателем, который дешифрует
|
||||
/// зашифрованный XML-документ. Шифрация и дешифрация осуществляется без использования сертификатов. Шифрация осуществляется с использованием
|
||||
/// случайного симметричного ключа, который в свою очередь шифруется с использованием открытого ключа получателя. Соответственно для дешифрации
|
||||
/// данных сначала расшифровывается случайный симметричный ключ с использованием закрытого ключа получателя.
|
||||
///
|
||||
/// Перед началом теста имитируется передача получателем своего открытого ключа отправителю. Для этого получатель извлекает информацию о закрытом
|
||||
/// ключе из контейнера ключей, формирует закрытый ключ для дешифрации XML и условно передает (экспортирует) отправителю информацию о своем открытом
|
||||
/// ключе. Отправитель в свою очередь принимает (импортирует) от получателя информацию о его открытом ключе и формирует открытый ключ для шифрации XML.
|
||||
///
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием случайного симметричного ключа, а затем дешифрует
|
||||
/// полученный зашифрованный документ. Случайный симметричного ключ в свою очередь шифруется открытым асимметричным ключом получателя и в зашифрованном
|
||||
/// виде добавляется в зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML с использованием контейнера ключей")]
|
||||
public class EncryptedXmlKeyContainerTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
|
||||
public void ShouldEncryptXmlWithGost_R3410_2001(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
|
||||
var certificate = testCase.Certificate;
|
||||
|
||||
// Получатель экспортирует отправителю информацию о своем открытом ключе
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2001_AsymmetricAlgorithm(keyContainer);
|
||||
var publicKeyInfo = privateKey.ExportParameters(false);
|
||||
|
||||
// Отправитель импортирует от получателя информацию о его открытом ключе
|
||||
var publicKey = new Gost_R3410_2001_AsymmetricAlgorithm();
|
||||
publicKey.ImportParameters(publicKeyInfo);
|
||||
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, publicKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, privateKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
|
||||
public void ShouldEncryptXmlWithGost_R3410_2012_256(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
|
||||
var certificate = testCase.Certificate;
|
||||
|
||||
// Получатель экспортирует отправителю информацию о своем открытом ключе
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
|
||||
var publicKeyInfo = privateKey.ExportParameters(false);
|
||||
|
||||
// Отправитель импортирует от получателя информацию о его открытом ключе
|
||||
var publicKey = new Gost_R3410_2012_256_AsymmetricAlgorithm();
|
||||
publicKey.ImportParameters(publicKeyInfo);
|
||||
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, publicKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, privateKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
|
||||
public void ShouldEncryptXmlWithGost_R3410_2012_512(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
|
||||
var certificate = testCase.Certificate;
|
||||
|
||||
// Получатель экспортирует отправителю информацию о своем открытом ключе
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(keyContainer);
|
||||
var publicKeyInfo = privateKey.ExportParameters(false);
|
||||
|
||||
// Отправитель импортирует от получателя информацию о его открытом ключе
|
||||
var publicKey = new Gost_R3410_2012_512_AsymmetricAlgorithm();
|
||||
publicKey.ImportParameters(publicKeyInfo);
|
||||
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, publicKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, privateKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, GostAsymmetricAlgorithm publicKey)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(publicKey.ProviderType);
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
var elementIndex = 0;
|
||||
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Создание случайного сессионного ключа
|
||||
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Шифрация элемента
|
||||
var encryptedData = encryptedXml.EncryptData(element, sessionKey, false);
|
||||
|
||||
// Шифрация сессионного ключа с использованием публичного асимметричного ключа
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKey);
|
||||
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Id = "EncryptedElement" + elementIndex++;
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
// Формирование информации о зашифрованном сессионном ключе
|
||||
var encryptedSessionKey = new EncryptedKey();
|
||||
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
|
||||
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm);
|
||||
encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoName { Value = "KeyName1" });
|
||||
|
||||
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, GostAsymmetricAlgorithm privateKey)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(privateKey.ProviderType, encryptedXmlDocument);
|
||||
|
||||
// Добавление ссылки на приватный асимметричный ключ
|
||||
encryptedXml.AddKeyNameMapping("KeyName1", privateKey);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML с использованием случайного сессионного ключа.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием случайного симметричного ключа,
|
||||
/// а затем дешифрует полученный зашифрованный документ. Случайный симметричного ключ в свою очередь шифруется общим симметричным
|
||||
/// ключом и в зашифрованном виде добавляется в зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML с использованием случайного сессионного ключа")]
|
||||
public class EncryptedXmlSessionKey
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptXml(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, sharedKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, sharedKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, GostSymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType);
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
var elementIndex = 0;
|
||||
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Создание случайного сессионного ключа
|
||||
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(sharedKey.ProviderType))
|
||||
{
|
||||
// Шифрация элемента
|
||||
var encryptedData = encryptedXml.EncryptData(element, sessionKey, false);
|
||||
|
||||
// Шифрация сессионного ключа с использованием общего симметричного ключа
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, sharedKey, GostKeyExchangeExportMethod.CryptoProKeyExport);
|
||||
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Id = "EncryptedElement" + elementIndex++;
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
// Формирование информации о зашифрованном сессионном ключе
|
||||
var encryptedSessionKey = new EncryptedKey();
|
||||
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
|
||||
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostCryptoProKeyExportUrl);
|
||||
encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoName { Value = "SharedKey1" });
|
||||
|
||||
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, GostSymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType, encryptedXmlDocument);
|
||||
|
||||
// Добавление ссылки на общий симметричный ключ
|
||||
encryptedXml.AddKeyNameMapping("SharedKey1", sharedKey);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML с использованием общего симметричного ключа.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует полученный зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML с использованием общего симметричного ключа")]
|
||||
public sealed class EncryptedXmlSharedKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptXml(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, sharedKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, sharedKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType);
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Шифрация элемента
|
||||
var encryptedData = encryptedXml.EncryptData(element, sharedKey, false);
|
||||
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sharedKey.AlgorithmName);
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, Gost_28147_89_SymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType, encryptedXmlDocument);
|
||||
|
||||
var nsManager = new XmlNamespaceManager(encryptedXmlDocument.NameTable);
|
||||
nsManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl);
|
||||
|
||||
// Поиск всех зашифрованных XML-элементов
|
||||
var encryptedDataList = encryptedXmlDocument.SelectNodes("//enc:EncryptedData", nsManager);
|
||||
|
||||
if (encryptedDataList != null)
|
||||
{
|
||||
foreach (XmlElement encryptedData in encryptedDataList)
|
||||
{
|
||||
// Загрузка элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.LoadXml(encryptedData);
|
||||
|
||||
// Расшифровка элемента EncryptedData
|
||||
var decryptedData = encryptedXml.DecryptData(elementEncryptedData, sharedKey);
|
||||
|
||||
// Замена элемента EncryptedData его расшифрованным представлением
|
||||
encryptedXml.ReplaceData(encryptedData, decryptedData);
|
||||
}
|
||||
}
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, шифрует его целиком с использованием сертификата, а затем дешифрует зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public sealed class KuznyechikEncryptedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
var publicKeyAlgorithm = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
|
||||
using (var sessionKey = new Gost_3412_K_SymmetricAlgorithm(publicKeyAlgorithm.ProviderType))
|
||||
{
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKeyAlgorithm);
|
||||
|
||||
var encryptedSessionKey = new EncryptedKey
|
||||
{
|
||||
CipherData = new CipherData(encryptedSessionKeyData),
|
||||
EncryptionMethod = new EncryptionMethod(publicKeyAlgorithm.KeyExchangeAlgorithm),
|
||||
};
|
||||
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
|
||||
var elementEncryptedData = new EncryptedData
|
||||
{
|
||||
EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName),
|
||||
};
|
||||
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xmlDocument.OuterXml);
|
||||
var encryptedData = encryptedXml.EncryptData(xmlBytes, sessionKey);
|
||||
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
GostEncryptedXml.ReplaceElement(xmlDocument.DocumentElement, elementEncryptedData, false);
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, шифрует его целиком с использованием сертификата, а затем дешифрует зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Магма")]
|
||||
public sealed class MagmaEncryptedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
var publicKeyAlgorithm = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
|
||||
using (var sessionKey = new Gost_3412_M_SymmetricAlgorithm(publicKeyAlgorithm.ProviderType))
|
||||
{
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKeyAlgorithm);
|
||||
|
||||
var encryptedSessionKey = new EncryptedKey
|
||||
{
|
||||
CipherData = new CipherData(encryptedSessionKeyData),
|
||||
EncryptionMethod = new EncryptionMethod(publicKeyAlgorithm.KeyExchangeAlgorithm),
|
||||
};
|
||||
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
|
||||
var elementEncryptedData = new EncryptedData
|
||||
{
|
||||
EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName),
|
||||
};
|
||||
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xmlDocument.OuterXml);
|
||||
var encryptedData = encryptedXml.EncryptData(xmlBytes, sessionKey);
|
||||
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
GostEncryptedXml.ReplaceElement(xmlDocument.DocumentElement, elementEncryptedData, false);
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи XML-документа с использованием сертификата.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием сертификата,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи XML-документа с использованием сертификата")]
|
||||
public class SignedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о сертификате, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи всего XML документа с использованием сертификата
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает весь документ с использованием сертификата,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи всего XML документа с использованием сертификата")]
|
||||
public class SignedXmlDocumentTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на весь документ и указание алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Метод преобразования для подписи всего документа
|
||||
dataReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о сертификате, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3410;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи XML-документа с использованием контейнера ключей.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием контейнера ключей,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи XML-документа с использованием контейнера ключей")]
|
||||
public class SignedXmlKeyContainerTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
|
||||
public void ShouldSignXmlWithGost_R3410_2001(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var signingKey = new Gost_R3410_2001_AsymmetricAlgorithm(keyContainer);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2001_KeyValue(signingKey));
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
|
||||
public void ShouldSignXmlWithGost_R3410_2012_256(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var signingKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2012_256_KeyValue(signingKey));
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
|
||||
public void ShouldSignXmlWithGost_R3410_2012_512(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var signingKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(keyContainer);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2012_512_KeyValue(signingKey));
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, GostKeyValue keyValue)
|
||||
{
|
||||
var signingKey = keyValue.PublicKey;
|
||||
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SigningKey = signingKey;
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(signingKey) };
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о ключе, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(keyValue);
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(GostAsymmetricAlgorithm signingKey)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var hashAlgorithm = signingKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи запроса к сервису СМЭВ (Система межведомственного электронного взаимодействия).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает запрос к сервису СМЭВ, подписывает определенную часть данного запроса с использованием сертификата,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи запроса к сервису СМЭВ (Система межведомственного электронного взаимодействия)")]
|
||||
public sealed class SignedXmlSmevTest
|
||||
{
|
||||
private const string WsSecurityExtNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
|
||||
private const string WsSecurityUtilityNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var smevRequest = CreateSmevRequest();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignSmevRequest(smevRequest, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifySmevRequestSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateSmevRequest()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SmevExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignSmevRequest(XmlDocument smevRequest, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(smevRequest) { GetIdElementHandler = GetSmevIdElement };
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#body", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
|
||||
var dataTransform = new XmlDsigExcC14NTransform();
|
||||
dataReference.AddTransform(dataTransform);
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
|
||||
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
|
||||
|
||||
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
|
||||
signedXml.SignedInfo.SignatureMethod = GetSignatureMethod(certificate);
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
smevRequest.GetElementsByTagName("ds:Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignatureValue")[0], true));
|
||||
smevRequest.GetElementsByTagName("ds:Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignedInfo")[0], true));
|
||||
smevRequest.GetElementsByTagName("wsse:BinarySecurityToken")[0].InnerText = Convert.ToBase64String(certificate.RawData);
|
||||
|
||||
return smevRequest;
|
||||
}
|
||||
|
||||
private static bool VerifySmevRequestSignature(XmlDocument signedSmevRequest)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedSmevRequest) { GetIdElementHandler = GetSmevIdElement };
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedSmevRequest.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Поиск ссылки на BinarySecurityToken
|
||||
var references = signedXml.KeyInfo.GetXml().GetElementsByTagName("Reference", WsSecurityExtNamespace);
|
||||
|
||||
if (references.Count > 0)
|
||||
{
|
||||
// Определение ссылки на сертификат (ссылка на узел документа)
|
||||
var binaryTokenReference = ((XmlElement)references[0]).GetAttribute("URI");
|
||||
|
||||
if (!string.IsNullOrEmpty(binaryTokenReference) && binaryTokenReference[0] == '#')
|
||||
{
|
||||
// Поиск элемента с закодированным в Base64 сертификатом
|
||||
var binaryTokenElement = signedXml.GetIdElement(signedSmevRequest, binaryTokenReference.Substring(1));
|
||||
|
||||
if (binaryTokenElement != null)
|
||||
{
|
||||
// Загрузка сертификата, который был использован для подписи
|
||||
var certificate = new X509Certificate2(Convert.FromBase64String(binaryTokenElement.InnerText));
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature(certificate.GetPublicKeyAlgorithm());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static XmlElement GetSmevIdElement(XmlDocument document, string idValue)
|
||||
{
|
||||
var namespaceManager = new XmlNamespaceManager(document.NameTable);
|
||||
namespaceManager.AddNamespace("wsu", WsSecurityUtilityNamespace);
|
||||
|
||||
return document.SelectSingleNode("//*[@wsu:Id='" + idValue + "']", namespaceManager) as XmlElement;
|
||||
}
|
||||
|
||||
private static string GetSignatureMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
{
|
||||
return publicKey.SignatureAlgorithm;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи XML-документа с предварительным XSLT-преобразованием подписываемых данных.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием сертификата,
|
||||
/// предварительно осуществляя XSLT-преобразование подписываемых данных, а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[Ignore("TODO: Нужно произвести диагностику с подключением логирования")]
|
||||
[TestFixture(Description = "Подпись и проверка подписи XML-документа с предварительным XSLT-преобразованием подписываемых данных")]
|
||||
public sealed class SignedXmlTransformTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Метод преобразования, применяемый к данным перед их подписью
|
||||
var dataTransform = CreateDataTransform();
|
||||
dataReference.AddTransform(dataTransform);
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о сертификате, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDsigXsltTransform CreateDataTransform()
|
||||
{
|
||||
var dataTransformDocument = new XmlDocument();
|
||||
|
||||
dataTransformDocument.LoadXml(@"
|
||||
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:ds='http://www.w3.org/2000/09/xmldsig#'>
|
||||
<xsl:template match='/'>
|
||||
<xsl:apply-templates />
|
||||
</xsl:template>
|
||||
<xsl:template match='*'>
|
||||
<xsl:copy>
|
||||
<xsl:copy-of select='@*' />
|
||||
<xsl:apply-templates />
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
<xsl:template match='ds:Signature' />
|
||||
</xsl:stylesheet>");
|
||||
|
||||
var dataTransform = new XmlDsigXsltTransform();
|
||||
dataTransform.LoadInnerXml(dataTransformDocument.ChildNodes);
|
||||
|
||||
return dataTransform;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn18BitCharString : Asn1CharString
|
||||
{
|
||||
public const int BitsPerCharA = 8;
|
||||
public const int BitsPerCharU = 7;
|
||||
|
||||
protected internal Asn18BitCharString(short typeCode)
|
||||
: base(typeCode)
|
||||
{
|
||||
}
|
||||
|
||||
protected internal Asn18BitCharString(string data, short typeCode)
|
||||
: base(data, typeCode)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
401
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerDecodeBuffer.cs
vendored
Normal file
401
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerDecodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerDecodeBuffer : Asn1DecodeBuffer
|
||||
{
|
||||
private readonly IntHolder _lenHolder;
|
||||
private readonly Asn1Tag _tagHolder;
|
||||
|
||||
private Asn1Tag _lastParsedTag;
|
||||
private MemoryStream _openTypeCaptureBuffer;
|
||||
private MemoryStream _parserCaptureBuffer;
|
||||
|
||||
public Asn1BerDecodeBuffer(byte[] msgdata)
|
||||
: base(msgdata)
|
||||
{
|
||||
_tagHolder = new Asn1Tag();
|
||||
_lenHolder = new IntHolder();
|
||||
}
|
||||
|
||||
public Asn1BerDecodeBuffer(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
_tagHolder = new Asn1Tag();
|
||||
_lenHolder = new IntHolder();
|
||||
}
|
||||
|
||||
public virtual Asn1Tag LastTag
|
||||
{
|
||||
get { return _lastParsedTag; }
|
||||
}
|
||||
|
||||
public static int CalcIndefLen(byte[] data, int offset, int len)
|
||||
{
|
||||
Asn1BerDecodeBuffer buffer;
|
||||
|
||||
if ((offset == 0) && (len == data.Length))
|
||||
{
|
||||
buffer = new Asn1BerDecodeBuffer(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var destinationArray = new byte[len];
|
||||
Array.Copy(data, offset, destinationArray, 0, len);
|
||||
buffer = new Asn1BerDecodeBuffer(destinationArray);
|
||||
}
|
||||
|
||||
var tag = new Asn1Tag();
|
||||
var num = buffer.DecodeTagAndLength(tag);
|
||||
|
||||
if (num == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
var num2 = 1;
|
||||
num = 0;
|
||||
|
||||
while (num2 > 0)
|
||||
{
|
||||
var byteCount = buffer.ByteCount;
|
||||
var num4 = buffer.DecodeTagAndLength(tag);
|
||||
num += buffer.ByteCount - byteCount;
|
||||
|
||||
if (num4 > 0)
|
||||
{
|
||||
buffer.Skip(num4);
|
||||
num += num4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num4 == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
num2++;
|
||||
continue;
|
||||
}
|
||||
if (tag.IsEoc() && (num4 == 0))
|
||||
{
|
||||
num2--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int DecodeLength()
|
||||
{
|
||||
var num3 = 0;
|
||||
var num2 = Read();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
if (num2 <= 0x80)
|
||||
{
|
||||
if (num2 == 0x80)
|
||||
{
|
||||
return Asn1Status.IndefiniteLength;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
var num = num2 & 0x7f;
|
||||
|
||||
if (num > 4)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
num2 = Read();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num3 = (num3 * 0x100) + num2;
|
||||
num--;
|
||||
}
|
||||
|
||||
return num3;
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeOpenType()
|
||||
{
|
||||
return DecodeOpenType(true);
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeOpenType(bool saveData)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
if (_openTypeCaptureBuffer == null)
|
||||
{
|
||||
_openTypeCaptureBuffer = new MemoryStream(0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
_openTypeCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_openTypeCaptureBuffer.SetLength(0L);
|
||||
}
|
||||
|
||||
AddCaptureBuffer(_openTypeCaptureBuffer);
|
||||
}
|
||||
|
||||
DecodeOpenTypeElement(_tagHolder, _lenHolder, saveData);
|
||||
|
||||
if (saveData)
|
||||
{
|
||||
var buffer = _openTypeCaptureBuffer.ToArray();
|
||||
RemoveCaptureBuffer(_openTypeCaptureBuffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void DecodeOpenTypeElement(Asn1Tag tag, IntHolder len, bool saveData)
|
||||
{
|
||||
var nbytes = DecodeTagAndLength(tag);
|
||||
var byteCount = base.ByteCount;
|
||||
|
||||
if (nbytes > 0)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
Capture(nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Skip(nbytes);
|
||||
}
|
||||
}
|
||||
else if (nbytes == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MovePastEoc(saveData);
|
||||
}
|
||||
|
||||
len.Value = base.ByteCount - byteCount;
|
||||
}
|
||||
|
||||
public virtual void DecodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
tag.Class = (short)(num & 0xc0);
|
||||
tag.Form = (short)(num & 0x20);
|
||||
tag.IdCode = num & 0x1f;
|
||||
|
||||
if (tag.IdCode == 0x1f)
|
||||
{
|
||||
var num2 = 0L;
|
||||
var num3 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num2 = (num2 * 0x80L) + (num & 0x7f);
|
||||
|
||||
if ((num2 > 0x7fffffffL) || (num3++ > 8))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidTagValue);
|
||||
}
|
||||
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
tag.IdCode = (int)num2;
|
||||
}
|
||||
|
||||
_lastParsedTag = tag;
|
||||
}
|
||||
|
||||
public virtual int DecodeTagAndLength(Asn1Tag tag)
|
||||
{
|
||||
DecodeTag(tag);
|
||||
return DecodeLength();
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(Asn1Tag tag)
|
||||
{
|
||||
return MatchTag(tag.Class, tag.Form, tag.IdCode, null, null);
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(Asn1Tag tag, Asn1Tag parsedTag, IntHolder parsedLen)
|
||||
{
|
||||
return MatchTag(tag.Class, tag.Form, tag.IdCode, parsedTag, parsedLen);
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(short tagClass, short tagForm, int tagIdCode, Asn1Tag parsedTag, IntHolder parsedLen)
|
||||
{
|
||||
Mark();
|
||||
|
||||
var tag = parsedTag ?? _tagHolder;
|
||||
var holder = parsedLen ?? _lenHolder;
|
||||
|
||||
holder.Value = DecodeTagAndLength(tag);
|
||||
|
||||
if (!tag.Equals(tagClass, tagForm, tagIdCode))
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void MovePastEoc(bool saveData)
|
||||
{
|
||||
var tag = new Asn1Tag();
|
||||
var num = 1;
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
var nbytes = DecodeTagAndLength(tag);
|
||||
|
||||
if (nbytes > 0)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
Capture(nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Skip(nbytes);
|
||||
}
|
||||
}
|
||||
else if (nbytes == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
else if (tag.IsEoc() && (nbytes == 0))
|
||||
{
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Parse(IAsn1TaggedEventHandler handler)
|
||||
{
|
||||
if (_parserCaptureBuffer == null)
|
||||
{
|
||||
RemoveCaptureBuffer(_parserCaptureBuffer);
|
||||
}
|
||||
|
||||
if (_parserCaptureBuffer == null)
|
||||
{
|
||||
_parserCaptureBuffer = new MemoryStream(0x100);
|
||||
AddCaptureBuffer(_parserCaptureBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
}
|
||||
|
||||
ParseElement(handler, _tagHolder, _lenHolder);
|
||||
}
|
||||
|
||||
private void ParseCons(IAsn1TaggedEventHandler handler, int len)
|
||||
{
|
||||
var tag2 = new Asn1Tag();
|
||||
var holder = new IntHolder();
|
||||
var byteCount = base.ByteCount;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ParseElement(handler, tag2, holder);
|
||||
|
||||
if (len == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
if (tag2.IsEoc() && (holder.Value == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((base.ByteCount - byteCount) >= len)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseElement(IAsn1TaggedEventHandler handler, Asn1Tag tag, IntHolder len)
|
||||
{
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
|
||||
len.Value = DecodeTagAndLength(tag);
|
||||
|
||||
if (!tag.IsEoc() || (len.Value != 0))
|
||||
{
|
||||
handler.StartElement(tag, len.Value, _parserCaptureBuffer.ToArray());
|
||||
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
|
||||
if ((len.Value > 0) || (len.Value == Asn1Status.IndefiniteLength))
|
||||
{
|
||||
if (tag.Constructed)
|
||||
{
|
||||
ParseCons(handler, len.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParsePrim(handler, len.Value);
|
||||
}
|
||||
}
|
||||
|
||||
handler.EndElement(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParsePrim(IAsn1TaggedEventHandler handler, int len)
|
||||
{
|
||||
var buffer = new byte[len];
|
||||
Read(buffer);
|
||||
handler.Contents(buffer);
|
||||
}
|
||||
|
||||
public virtual Asn1Tag PeekTag()
|
||||
{
|
||||
var parsedTag = new Asn1Tag();
|
||||
PeekTag(parsedTag);
|
||||
return parsedTag;
|
||||
}
|
||||
|
||||
public virtual void PeekTag(Asn1Tag parsedTag)
|
||||
{
|
||||
Mark();
|
||||
DecodeTag(parsedTag);
|
||||
Reset();
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
return Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerDecodeContext
|
||||
{
|
||||
private readonly int _decBufByteCount;
|
||||
private readonly Asn1BerDecodeBuffer _decodeBuffer;
|
||||
private readonly int _elemLength;
|
||||
private readonly Asn1Tag _tagHolder;
|
||||
|
||||
public Asn1BerDecodeContext(Asn1BerDecodeBuffer decodeBuffer, int elemLength)
|
||||
{
|
||||
_decodeBuffer = decodeBuffer;
|
||||
_decBufByteCount = decodeBuffer.ByteCount;
|
||||
_elemLength = elemLength;
|
||||
_tagHolder = new Asn1Tag();
|
||||
}
|
||||
|
||||
public virtual bool Expired()
|
||||
{
|
||||
if (_elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
var parsedLen = new IntHolder();
|
||||
var flag = _decodeBuffer.MatchTag(0, 0, 0, null, parsedLen);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
_decodeBuffer.Reset();
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
var num = _decodeBuffer.ByteCount - _decBufByteCount;
|
||||
|
||||
return (num >= _elemLength);
|
||||
}
|
||||
|
||||
public virtual bool MatchElemTag(Asn1Tag tag, IntHolder parsedLen, bool advance)
|
||||
{
|
||||
return MatchElemTag(tag.Class, tag.Form, tag.IdCode, parsedLen, advance);
|
||||
}
|
||||
|
||||
public virtual bool MatchElemTag(short tagClass, short tagForm, int tagIdCode, IntHolder parsedLen, bool advance)
|
||||
{
|
||||
if (Expired())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var flag = _decodeBuffer.MatchTag(tagClass, tagForm, tagIdCode, _tagHolder, parsedLen);
|
||||
|
||||
if ((_elemLength != Asn1Status.IndefiniteLength) && (parsedLen.Value != Asn1Status.IndefiniteLength))
|
||||
{
|
||||
var num = _decodeBuffer.ByteCount - _decBufByteCount;
|
||||
|
||||
if ((parsedLen.Value < 0) || (parsedLen.Value > (_elemLength - num)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag && !advance)
|
||||
{
|
||||
_decodeBuffer.Reset();
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
305
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerEncodeBuffer.cs
vendored
Normal file
305
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerEncodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerEncodeBuffer : Asn1EncodeBuffer
|
||||
{
|
||||
public Asn1BerEncodeBuffer()
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
|
||||
public Asn1BerEncodeBuffer(int sizeIncrement)
|
||||
: base(sizeIncrement)
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
|
||||
public virtual MemoryStream ByteArrayInputStream
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = ByteIndex + 1;
|
||||
return new MemoryStream(Data, index, Data.Length - index);
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] MsgCopy
|
||||
{
|
||||
get
|
||||
{
|
||||
var sourceIndex = ByteIndex + 1;
|
||||
var length = Data.Length - sourceIndex;
|
||||
var destinationArray = new byte[length];
|
||||
|
||||
Array.Copy(Data, sourceIndex, destinationArray, 0, length);
|
||||
|
||||
return destinationArray;
|
||||
}
|
||||
}
|
||||
|
||||
public override int MsgLength
|
||||
{
|
||||
get
|
||||
{
|
||||
var num = ByteIndex + 1;
|
||||
return (Data.Length - num);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BinDump()
|
||||
{
|
||||
BinDump(null);
|
||||
}
|
||||
|
||||
public override void BinDump(StreamWriter outs, string varName)
|
||||
{
|
||||
var buffer = new Asn1BerDecodeBuffer(ByteArrayInputStream);
|
||||
|
||||
try
|
||||
{
|
||||
buffer.Parse(new Asn1BerMessageDumpHandler(outs));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.Out.WriteLine(exception.Message);
|
||||
Console.Error.Write(exception.StackTrace);
|
||||
Console.Error.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override void CheckSize(int bytesRequired)
|
||||
{
|
||||
if (bytesRequired > (ByteIndex + 1))
|
||||
{
|
||||
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
|
||||
var num2 = num * SizeIncrement;
|
||||
var destinationArray = new byte[Data.Length + num2];
|
||||
var destinationIndex = (ByteIndex + num2) + 1;
|
||||
var length = Data.Length - (ByteIndex + 1);
|
||||
|
||||
Array.Copy(Data, ByteIndex + 1, destinationArray, destinationIndex, length);
|
||||
|
||||
Data = destinationArray;
|
||||
ByteIndex = destinationIndex - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Copy(byte data)
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex--] = data;
|
||||
}
|
||||
|
||||
public override void Copy(byte[] data)
|
||||
{
|
||||
CheckSize(data.Length);
|
||||
ByteIndex -= data.Length;
|
||||
|
||||
Array.Copy(data, 0, Data, ByteIndex + 1, data.Length);
|
||||
}
|
||||
|
||||
public virtual void Copy(string data)
|
||||
{
|
||||
var length = data.Length;
|
||||
CheckSize(length);
|
||||
ByteIndex -= length;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
Data[(ByteIndex + i) + 1] = (byte)data[i];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Copy(byte[] data, int startOffset, int length)
|
||||
{
|
||||
CheckSize(length);
|
||||
ByteIndex -= length;
|
||||
|
||||
Array.Copy(data, startOffset, Data, ByteIndex + 1, length);
|
||||
}
|
||||
|
||||
public virtual int EncodeIdentifier(int ident)
|
||||
{
|
||||
var flag = true;
|
||||
var num = 0;
|
||||
var num2 = ident;
|
||||
|
||||
do
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex] = (byte)(num2 % 0x80);
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
Data[ByteIndex] = (byte)(Data[ByteIndex] | 0x80);
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
ByteIndex--;
|
||||
num2 /= 0x80;
|
||||
num++;
|
||||
|
||||
}
|
||||
while (num2 > 0);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int EncodeIntValue(long ivalue)
|
||||
{
|
||||
long num2;
|
||||
long num = ivalue;
|
||||
|
||||
var num3 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num2 = num % 0x100L;
|
||||
num /= 0x100L;
|
||||
|
||||
if ((num < 0L) && (num2 != 0L))
|
||||
{
|
||||
num -= 1L;
|
||||
}
|
||||
|
||||
Copy((byte)num2);
|
||||
|
||||
num3++;
|
||||
}
|
||||
while ((num != 0L) && (num != -1L));
|
||||
|
||||
if ((ivalue > 0L) && ((num2 & 0x80L) == 0x80L))
|
||||
{
|
||||
Copy(0);
|
||||
num3++;
|
||||
return num3;
|
||||
}
|
||||
|
||||
if ((ivalue < 0L) && ((num2 & 0x80L) == 0L))
|
||||
{
|
||||
Copy(0xff);
|
||||
num3++;
|
||||
}
|
||||
|
||||
return num3;
|
||||
}
|
||||
|
||||
public virtual int EncodeLength(int len)
|
||||
{
|
||||
var num = 0;
|
||||
|
||||
bool flag;
|
||||
|
||||
if (len >= 0)
|
||||
{
|
||||
flag = len > 0x7f;
|
||||
|
||||
var num2 = len;
|
||||
|
||||
do
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex--] = (byte)(num2 % 0x100);
|
||||
num++;
|
||||
num2 /= 0x100;
|
||||
}
|
||||
while (num2 > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = len == Asn1Status.IndefiniteLength;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex--] = (byte)(num | 0x80);
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int EncodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
|
||||
var num2 = 0;
|
||||
|
||||
if (tag.IdCode < 0x1f)
|
||||
{
|
||||
Copy((byte)(num | tag.IdCode));
|
||||
num2++;
|
||||
return num2;
|
||||
}
|
||||
|
||||
num2 += EncodeIdentifier(tag.IdCode);
|
||||
Copy((byte)(num | 0x1f));
|
||||
num2++;
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
public virtual int EncodeTagAndLength(Asn1Tag tag, int len)
|
||||
{
|
||||
return (EncodeLength(len) + EncodeTag(tag));
|
||||
}
|
||||
|
||||
public virtual int EncodeTagAndLength(short tagClass, short tagForm, int tagIdCode, int len)
|
||||
{
|
||||
var tag = new Asn1Tag(tagClass, tagForm, tagIdCode);
|
||||
return EncodeTagAndLength(tag, len);
|
||||
}
|
||||
|
||||
public override Stream GetInputStream()
|
||||
{
|
||||
return ByteArrayInputStream;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
ByteIndex = Data.Length - 1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var num = ByteIndex + 1;
|
||||
var num2 = Data.Length - num;
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
for (var i = 0; i < num2; ++i)
|
||||
{
|
||||
str = str + Asn1Util.ToHexString(Data[i + num]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public override void Write(Stream outs)
|
||||
{
|
||||
var offset = ByteIndex + 1;
|
||||
outs.Write(Data, offset, Data.Length - offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerInputStream : Asn1BerDecodeBuffer, IAsn1InputStream
|
||||
{
|
||||
public Asn1BerInputStream(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Available()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
var num = inputStream.Length - inputStream.Position;
|
||||
return (int)num;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
inputStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool MarkSupported()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
return ((inputStream != null) && inputStream.CanSeek);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerMessageDumpHandler : IAsn1TaggedEventHandler
|
||||
{
|
||||
private const int MaxBytesPerLine = 12;
|
||||
|
||||
private int _offset;
|
||||
private readonly StreamWriter _printStream;
|
||||
|
||||
public Asn1BerMessageDumpHandler()
|
||||
{
|
||||
_printStream = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true };
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
public Asn1BerMessageDumpHandler(StreamWriter outs)
|
||||
{
|
||||
_printStream = outs;
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
public virtual void Contents(byte[] data)
|
||||
{
|
||||
if (data.Length != 0)
|
||||
{
|
||||
PrintOffset();
|
||||
|
||||
var flag = true;
|
||||
var builder = new StringBuilder(100);
|
||||
var builder2 = new StringBuilder(100);
|
||||
|
||||
for (var i = 0; i < data.Length; ++i)
|
||||
{
|
||||
builder.Append(Asn1Util.ToHexString(data[i]));
|
||||
builder.Append(' ');
|
||||
|
||||
int num2 = data[i];
|
||||
|
||||
if ((num2 >= 0x20) && (num2 <= 0x7f))
|
||||
{
|
||||
builder2.Append((char)num2);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder2.Append('.');
|
||||
}
|
||||
|
||||
if (((i + 1) % MaxBytesPerLine) == 0)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
_printStream.Write(" : ");
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
_printStream.WriteLine(builder + ": " + builder2);
|
||||
|
||||
builder.Length = 0;
|
||||
builder2.Length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
while (builder.Length < 0x24)
|
||||
{
|
||||
builder.Append(' ');
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
_printStream.Write(" : ");
|
||||
}
|
||||
|
||||
_printStream.WriteLine(builder + ": " + builder2);
|
||||
}
|
||||
|
||||
_offset += data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EndElement(Asn1Tag tag)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void StartElement(Asn1Tag tag, int len, byte[] tagLenBytes)
|
||||
{
|
||||
PrintOffset();
|
||||
|
||||
new StringBuilder(40); // WTF?
|
||||
|
||||
var index = 0;
|
||||
|
||||
while (index < tagLenBytes.Length)
|
||||
{
|
||||
_printStream.Write(Asn1Util.ToHexString(tagLenBytes[index]));
|
||||
_printStream.Write(' ');
|
||||
index++;
|
||||
}
|
||||
|
||||
while (index < MaxBytesPerLine)
|
||||
{
|
||||
_printStream.Write(" ");
|
||||
index++;
|
||||
}
|
||||
|
||||
_printStream.Write(": ");
|
||||
_printStream.Write(tag.Constructed ? "C " : "P ");
|
||||
_printStream.Write(tag + " ");
|
||||
_printStream.WriteLine(Convert.ToString(len));
|
||||
_offset += tagLenBytes.Length;
|
||||
}
|
||||
|
||||
private void PrintOffset()
|
||||
{
|
||||
var str = Convert.ToString(_offset);
|
||||
var num = 4 - str.Length;
|
||||
|
||||
for (var i = 0; i < num; ++i)
|
||||
{
|
||||
_printStream.Write('0');
|
||||
}
|
||||
|
||||
_printStream.Write(str);
|
||||
_printStream.Write(" : ");
|
||||
}
|
||||
}
|
||||
}
|
||||
277
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerOutputStream.cs
vendored
Normal file
277
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerOutputStream.cs
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerOutputStream : Asn1OutputStream
|
||||
{
|
||||
private static readonly byte[] Eoc = new byte[2];
|
||||
|
||||
public Asn1BerOutputStream(Stream outputStream)
|
||||
: base(new BufferedStream(outputStream))
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1BerOutputStream(Stream outputStream, int bufSize)
|
||||
: base((bufSize == 0) ? outputStream : new BufferedStream(outputStream, bufSize))
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Encode(Asn1Type type, bool explicitTagging)
|
||||
{
|
||||
type.Encode(this, explicitTagging);
|
||||
}
|
||||
|
||||
public virtual void EncodeBitString(byte[] data, int numbits, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
|
||||
var count = (numbits + 7) / 8;
|
||||
EncodeLength(count + 1);
|
||||
|
||||
var num2 = numbits % 8;
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
num2 = 8 - num2;
|
||||
data[count - 1] = (byte)(data[count - 1] & ((byte)~((1 << num2) - 1)));
|
||||
}
|
||||
|
||||
OutputStream.WriteByte((byte)num2);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
OutputStream.Write(data, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeBmpString(string data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length * 2);
|
||||
|
||||
var length = data.Length;
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var num3 = data[i];
|
||||
var num2 = num3 / 0x100;
|
||||
var num = num3 % 0x100;
|
||||
|
||||
OutputStream.WriteByte((byte)num2);
|
||||
OutputStream.WriteByte((byte)num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeCharString(string data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length);
|
||||
var buffer = Asn1Util.ToByteArray(data);
|
||||
OutputStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeEoc()
|
||||
{
|
||||
OutputStream.Write(Eoc, 0, Eoc.Length);
|
||||
}
|
||||
|
||||
public virtual void EncodeIdentifier(long ident)
|
||||
{
|
||||
var number = 0x7fL;
|
||||
var identBytesCount = Asn1RunTime.GetIdentBytesCount(ident);
|
||||
|
||||
number = number << (7 * identBytesCount);
|
||||
|
||||
if (identBytesCount > 0)
|
||||
{
|
||||
while (identBytesCount > 0)
|
||||
{
|
||||
number = Asn1Util.UrShift(number, 7);
|
||||
identBytesCount--;
|
||||
|
||||
var num3 = Asn1Util.UrShift(ident & number, identBytesCount * 7);
|
||||
|
||||
if (identBytesCount != 0)
|
||||
{
|
||||
num3 |= 0x80L;
|
||||
}
|
||||
|
||||
OutputStream.WriteByte((byte)num3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeIntValue(long data, bool encodeLen)
|
||||
{
|
||||
long num2;
|
||||
var num = data;
|
||||
var buffer = new byte[9];
|
||||
var len = 0;
|
||||
var length = buffer.Length;
|
||||
|
||||
do
|
||||
{
|
||||
num2 = num % 0x100L;
|
||||
num /= 0x100L;
|
||||
|
||||
if ((num < 0L) && (num2 != 0L))
|
||||
{
|
||||
num -= 1L;
|
||||
}
|
||||
|
||||
buffer[--length] = (byte)num2;
|
||||
len++;
|
||||
}
|
||||
while ((num != 0L) && (num != -1L));
|
||||
|
||||
if ((data > 0L) && ((num2 & 0x80L) == 0x80L))
|
||||
{
|
||||
buffer[--length] = 0;
|
||||
len++;
|
||||
}
|
||||
else if ((data < 0L) && ((num2 & 0x80L) == 0L))
|
||||
{
|
||||
buffer[--length] = 0xff;
|
||||
len++;
|
||||
}
|
||||
|
||||
if (encodeLen)
|
||||
{
|
||||
EncodeLength(len);
|
||||
}
|
||||
|
||||
OutputStream.Write(buffer, length, len);
|
||||
}
|
||||
|
||||
public virtual void EncodeLength(int len)
|
||||
{
|
||||
if (len >= 0)
|
||||
{
|
||||
var bytesCount = Asn1Util.GetBytesCount(len);
|
||||
|
||||
if (len > 0x7f)
|
||||
{
|
||||
OutputStream.WriteByte((byte)(bytesCount | 0x80));
|
||||
}
|
||||
for (var i = (8 * bytesCount) - 8; i >= 0; i -= 8)
|
||||
{
|
||||
var num3 = (byte)((len >> i) & 0xff);
|
||||
OutputStream.WriteByte(num3);
|
||||
}
|
||||
}
|
||||
else if (len == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeOctetString(byte[] data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length);
|
||||
OutputStream.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
|
||||
if (tag.IdCode < 0x1f)
|
||||
{
|
||||
OutputStream.WriteByte((byte)(num | tag.IdCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte((byte)(num | 0x1f));
|
||||
EncodeIdentifier(tag.IdCode);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeTag(short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
||||
}
|
||||
|
||||
public virtual void EncodeTagAndIndefLen(Asn1Tag tag)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
public virtual void EncodeTagAndIndefLen(short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
public virtual void EncodeTagAndLength(Asn1Tag tag, int len)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
EncodeLength(len);
|
||||
}
|
||||
|
||||
public virtual void EncodeUnivString(int[] data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length * 4);
|
||||
var length = data.Length;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
var number = data[i];
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x18) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x10) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 8) & 0xff));
|
||||
OutputStream.WriteByte((byte)(number & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BigInteger.cs
vendored
Normal file
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BigInteger.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1BigInteger : Asn1Type
|
||||
{
|
||||
private const int MaxBigIntLen = 0x186a0;
|
||||
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode);
|
||||
public static readonly BigInteger Zero = new BigInteger();
|
||||
|
||||
private BigInteger _value;
|
||||
|
||||
public Asn1BigInteger()
|
||||
{
|
||||
_value = new BigInteger();
|
||||
}
|
||||
|
||||
public Asn1BigInteger(BigInteger value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public Asn1BigInteger(string value)
|
||||
{
|
||||
_value = new BigInteger(value);
|
||||
}
|
||||
|
||||
public Asn1BigInteger(string value, int radix)
|
||||
{
|
||||
_value = new BigInteger(value, radix);
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
_value = DecodeValue(buffer, length);
|
||||
buffer.TypeCode = 2;
|
||||
}
|
||||
|
||||
public BigInteger DecodeValue(Asn1DecodeBuffer buffer, int length)
|
||||
{
|
||||
var ivalue = new byte[length];
|
||||
|
||||
if (length > MaxBigIntLen)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1TooBigIntegerValue, length);
|
||||
}
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
ivalue[i] = (byte)buffer.ReadByte();
|
||||
}
|
||||
|
||||
var integer = new BigInteger();
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
integer.SetData(ivalue);
|
||||
}
|
||||
|
||||
return integer;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = EncodeValue(buffer, _value, true);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
var buffer = new Asn1BerEncodeBuffer();
|
||||
var len = EncodeValue(buffer, _value, true);
|
||||
|
||||
outs.EncodeLength(len);
|
||||
outs.Write(buffer.MsgCopy);
|
||||
}
|
||||
|
||||
private static int EncodeValue(Asn1EncodeBuffer buffer, BigInteger ivalue, bool doCopy)
|
||||
{
|
||||
var data = ivalue.GetData();
|
||||
var length = data.Length;
|
||||
|
||||
for (var i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (doCopy)
|
||||
{
|
||||
buffer.Copy(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public virtual bool Equals(long value)
|
||||
{
|
||||
return _value.Equals(value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var integer = value as Asn1BigInteger;
|
||||
|
||||
if (integer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _value.Equals(integer._value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _value.ToString(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
455
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BitString.cs
vendored
Normal file
455
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BitString.cs
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1BitString : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BitStringTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public byte[] Value;
|
||||
|
||||
[NonSerialized]
|
||||
public int NumBits;
|
||||
|
||||
public Asn1BitString()
|
||||
{
|
||||
NumBits = 0;
|
||||
Value = null;
|
||||
}
|
||||
|
||||
public Asn1BitString(bool[] bitValues)
|
||||
{
|
||||
AllocBitArray(bitValues.Length);
|
||||
|
||||
var index = 0;
|
||||
var num4 = 0x80;
|
||||
var num = 0;
|
||||
var num2 = 0;
|
||||
|
||||
while (num < bitValues.Length)
|
||||
{
|
||||
if (bitValues[num])
|
||||
{
|
||||
num2 |= num4;
|
||||
}
|
||||
|
||||
num4 = num4 >> 1;
|
||||
|
||||
if (num4 == 0)
|
||||
{
|
||||
Value[index++] = (byte)num2;
|
||||
num4 = 0x80;
|
||||
num2 = 0;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num4 != 0x80)
|
||||
{
|
||||
Value[index] = (byte)num2;
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1BitString(BitArray bitArray)
|
||||
{
|
||||
AllocBitArray(bitArray.Length);
|
||||
|
||||
var index = 0;
|
||||
var num4 = 0x80;
|
||||
var num = 0;
|
||||
var num2 = 0;
|
||||
|
||||
while (num < bitArray.Length)
|
||||
{
|
||||
if (bitArray.Get(num))
|
||||
{
|
||||
num2 |= num4;
|
||||
}
|
||||
|
||||
num4 = num4 >> 1;
|
||||
|
||||
if (num4 == 0)
|
||||
{
|
||||
Value[index++] = (byte)num2;
|
||||
num4 = 0x80;
|
||||
num2 = 0;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num4 != 0x80)
|
||||
{
|
||||
Value[index] = (byte)num2;
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1BitString(string value)
|
||||
{
|
||||
var numbits = new IntHolder();
|
||||
Value = Asn1Value.ParseString(value, numbits);
|
||||
|
||||
NumBits = numbits.Value;
|
||||
}
|
||||
|
||||
public Asn1BitString(int numBits, byte[] data)
|
||||
{
|
||||
NumBits = numBits;
|
||||
Value = data;
|
||||
}
|
||||
|
||||
private void AllocBitArray(int numbits)
|
||||
{
|
||||
NumBits = numbits;
|
||||
|
||||
var num = (NumBits + 7) / 8;
|
||||
|
||||
if ((Value == null) || (Value.Length < num))
|
||||
{
|
||||
Value = new byte[num];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear(int bitIndex)
|
||||
{
|
||||
this[bitIndex] = false;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
if (elemLength < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
if (elemLength != 0)
|
||||
{
|
||||
var num8 = elemLength - 1;
|
||||
var num7 = buffer.Read();
|
||||
|
||||
if (num7 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
if ((num7 < 0) || (num7 > 7))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num7);
|
||||
}
|
||||
|
||||
if ((num8 == 0) && (num7 != 0))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
NumBits = (num8 * 8) - num7;
|
||||
Value = new byte[num8];
|
||||
buffer.Read(Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
NumBits = 0;
|
||||
Value = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var num3 = 0;
|
||||
var offset = 0;
|
||||
var index = -1;
|
||||
var num6 = 0;
|
||||
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var nbytes = MatchTag(buffer, Tag);
|
||||
|
||||
if (nbytes <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
num3 += nbytes;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
AllocBitArray(num3 * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReallocBitArray(num3 * 8);
|
||||
}
|
||||
|
||||
index = offset;
|
||||
buffer.Read(Value, offset, nbytes);
|
||||
offset = num3;
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
num6 = Value[index];
|
||||
|
||||
if (((offset - index) - 1) > 0)
|
||||
{
|
||||
Array.Copy(Value, index + 1, Value, index, (offset - index) - 1);
|
||||
}
|
||||
|
||||
num3--;
|
||||
}
|
||||
|
||||
if ((num6 < 0) || (num6 > 7))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num6);
|
||||
}
|
||||
|
||||
ReallocBitArray((num3 * 8) - num6);
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = 3;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var length = (NumBits + 7) / 8;
|
||||
var num2 = NumBits % 8;
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
num2 = 8 - num2;
|
||||
Value[length - 1] = (byte)(Value[length - 1] & ((byte)~((1 << num2) - 1)));
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
buffer.Copy(Value, 0, length);
|
||||
}
|
||||
|
||||
buffer.Copy((byte)num2);
|
||||
length++;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeBitString(Value, NumBits, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1BitString;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(str.NumBits, str.Value);
|
||||
}
|
||||
|
||||
public virtual bool Equals(int nbits, byte[] value)
|
||||
{
|
||||
if (nbits != NumBits)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var num = ((nbits - 1) / 8) + 1;
|
||||
|
||||
for (var i = 0; i < num; ++i)
|
||||
{
|
||||
if (value[i] != Value[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool Get(int bitno)
|
||||
{
|
||||
var index = bitno / 8;
|
||||
var num2 = 1 << (7 - (bitno % 8));
|
||||
|
||||
if ((Value != null) && (Value.Length >= index))
|
||||
{
|
||||
int num3 = Value[index];
|
||||
return ((num3 & num2) != 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
private void ReallocBitArray(int numbits)
|
||||
{
|
||||
NumBits = numbits;
|
||||
var num = (NumBits + 7) / 8;
|
||||
|
||||
if (Value.Length != num)
|
||||
{
|
||||
var value = Value;
|
||||
Value = new byte[num];
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
Array.Copy(value, 0, Value, 0, Math.Min(value.Length, num));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Set(int bitIndex)
|
||||
{
|
||||
Set(bitIndex, true);
|
||||
}
|
||||
|
||||
public virtual void Set(int bitIndex, bool value)
|
||||
{
|
||||
var index = bitIndex / 8;
|
||||
var num2 = 1 << (7 - (bitIndex % 8));
|
||||
var num3 = index + 1;
|
||||
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new byte[num3];
|
||||
}
|
||||
else if (Value.Length < num3)
|
||||
{
|
||||
var destinationArray = new byte[num3];
|
||||
Array.Copy(Value, 0, destinationArray, 0, Value.Length);
|
||||
Value = destinationArray;
|
||||
}
|
||||
|
||||
int num4 = Value[index];
|
||||
num4 = value ? (num4 | num2) : (num4 & ~num2);
|
||||
Value[index] = (byte)num4;
|
||||
|
||||
if ((bitIndex + 1) > NumBits)
|
||||
{
|
||||
NumBits = bitIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool[] ToBoolArray()
|
||||
{
|
||||
var flagArray = new bool[NumBits];
|
||||
|
||||
var num4 = 0;
|
||||
var numbits = NumBits;
|
||||
|
||||
foreach (var num3 in Value)
|
||||
{
|
||||
var num5 = 0x80;
|
||||
var num = (numbits < 8) ? numbits : 8;
|
||||
|
||||
for (var j = 0; j < num; ++j)
|
||||
{
|
||||
flagArray[num4++] = (num3 & num5) != 0;
|
||||
num5 = num5 >> 1;
|
||||
}
|
||||
|
||||
numbits -= 8;
|
||||
}
|
||||
|
||||
return flagArray;
|
||||
}
|
||||
|
||||
public virtual string ToHexString()
|
||||
{
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
foreach (var b in Value)
|
||||
{
|
||||
str = str + Asn1Util.ToHexString(b);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
if (NumBits <= 0x10)
|
||||
{
|
||||
if (NumBits != 0)
|
||||
{
|
||||
var flagArray = ToBoolArray();
|
||||
|
||||
foreach (bool b in flagArray)
|
||||
{
|
||||
str = str + (b ? "1" : "0");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
var num2 = 4;
|
||||
var capacity = (NumBits + 3) / 4;
|
||||
var builder = new StringBuilder(capacity);
|
||||
|
||||
if (Value != null)
|
||||
{
|
||||
var num4 = 0;
|
||||
var index = 0;
|
||||
|
||||
while (num4 < capacity)
|
||||
{
|
||||
var num6 = (Value[index] >> num2) & 15;
|
||||
builder.Append((char)(num6 + ((num6 >= 10) ? 0x57 : 0x30)));
|
||||
num2 -= 4;
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
num2 = 4;
|
||||
index++;
|
||||
}
|
||||
|
||||
num4++;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public virtual bool this[int bitIndex]
|
||||
{
|
||||
get { return Get(bitIndex); }
|
||||
set { Set(bitIndex, value); }
|
||||
}
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return NumBits; }
|
||||
}
|
||||
}
|
||||
}
|
||||
125
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BmpString.cs
vendored
Normal file
125
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BmpString.cs
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1BmpString : Asn1CharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BmpStringTypeCode);
|
||||
|
||||
public Asn1BmpString()
|
||||
: base(BmpStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1BmpString(string data)
|
||||
: base(data, BmpStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var len = elemLength;
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
sb.EnsureCapacity(elemLength / 2);
|
||||
ReadSegment(buffer, sb, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
var capacity = 0;
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num3 = MatchTag(buffer, Asn1OctetString.Tag);
|
||||
|
||||
if (num3 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
capacity += num3;
|
||||
sb.EnsureCapacity(capacity);
|
||||
ReadSegment(buffer, sb, num3);
|
||||
}
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
Value = sb.ToString();
|
||||
buffer.TypeCode = BmpStringTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var length = Value.Length;
|
||||
|
||||
for (var i = length - 1; i >= 0; --i)
|
||||
{
|
||||
var num3 = Value[i];
|
||||
var num = num3 % 0x100;
|
||||
var num2 = num3 / 0x100;
|
||||
|
||||
buffer.Copy((byte)num);
|
||||
buffer.Copy((byte)num2);
|
||||
}
|
||||
|
||||
length *= 2;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeBmpString(Value, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
private static void ReadSegment(Asn1DecodeBuffer buffer, StringBuilder sb, int len)
|
||||
{
|
||||
if ((len % 2) != 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
var num = buffer.Read();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
var num2 = num * 0x100;
|
||||
len--;
|
||||
num = buffer.Read();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
num2 += num;
|
||||
len--;
|
||||
sb.Append((char)num2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Boolean.cs
vendored
Normal file
102
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Boolean.cs
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Boolean : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BooleanTypeCode);
|
||||
public static readonly Asn1Boolean FalseValue = new Asn1Boolean(false);
|
||||
public static readonly Asn1Boolean TrueValue = new Asn1Boolean(true);
|
||||
|
||||
[NonSerialized]
|
||||
public bool Value;
|
||||
|
||||
public Asn1Boolean()
|
||||
{
|
||||
Value = false;
|
||||
}
|
||||
|
||||
public Asn1Boolean(bool value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
MatchTag(buffer, Tag);
|
||||
}
|
||||
|
||||
var num = buffer.Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
buffer.TypeCode = BooleanTypeCode;
|
||||
Value = num != 0;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 1;
|
||||
|
||||
buffer.Copy(Value ? byte.MaxValue : ((byte)0));
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(1);
|
||||
outs.WriteByte(Value ? -1 : 0);
|
||||
}
|
||||
|
||||
public virtual bool Equals(bool value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var flag = value as Asn1Boolean;
|
||||
|
||||
if (flag == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Value == flag.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (!Value)
|
||||
{
|
||||
return "FALSE";
|
||||
}
|
||||
|
||||
return "TRUE";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1CerInputStream : Asn1BerInputStream
|
||||
{
|
||||
public Asn1CerInputStream(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
236
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CerOutputStream.cs
vendored
Normal file
236
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CerOutputStream.cs
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1CerOutputStream : Asn1BerOutputStream
|
||||
{
|
||||
public Asn1CerOutputStream(Stream outputStream)
|
||||
: base(outputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1CerOutputStream(Stream outputStream, int bufSize)
|
||||
: base(outputStream, bufSize)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Encode(Asn1Type type, bool explicitTagging)
|
||||
{
|
||||
type.Encode(this, explicitTagging);
|
||||
}
|
||||
|
||||
public override void EncodeBitString(byte[] value, int numbits, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((((numbits + 7) / 8) + 1) <= 0x3e8)
|
||||
{
|
||||
base.EncodeBitString(value, numbits, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1BitString.Tag.Class, 0x20, Asn1BitString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
var num = (numbits + 7) / 8;
|
||||
var num2 = numbits % 8;
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
num2 = 8 - num2;
|
||||
value[num - 1] = (byte)(value[num - 1] & ((byte)~((1 << num2) - 1)));
|
||||
}
|
||||
|
||||
for (var i = 0; i < num; i += 0x3e8)
|
||||
{
|
||||
var len = num - i;
|
||||
|
||||
if (len > 0x3e8)
|
||||
{
|
||||
len = 0x3e8;
|
||||
EncodeTagAndLength(Asn1BitString.Tag, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeTagAndLength(Asn1BitString.Tag, len + 1);
|
||||
OutputStream.WriteByte((byte)num2);
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
OutputStream.Write(value, i, len);
|
||||
}
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeBmpString(string value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 500))
|
||||
{
|
||||
base.EncodeBmpString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1BmpString.Tag.Class, 0x20, Asn1BmpString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i += 500)
|
||||
{
|
||||
var num2 = value.Length - i;
|
||||
|
||||
if (num2 > 500)
|
||||
{
|
||||
num2 = 500;
|
||||
}
|
||||
|
||||
EncodeTagAndLength(Asn1OctetString.Tag, num2 * 2);
|
||||
|
||||
for (var j = 0; j < num2; j++)
|
||||
{
|
||||
var num5 = value[j + i];
|
||||
var num4 = num5 / 0x100;
|
||||
|
||||
var num3 = num5 % 0x100;
|
||||
OutputStream.WriteByte((byte)num4);
|
||||
OutputStream.WriteByte((byte)num3);
|
||||
}
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeCharString(string value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 0x3e8))
|
||||
{
|
||||
base.EncodeCharString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = Asn1Util.ToByteArray(value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag.Class, 0x20, tag.IdCode);
|
||||
}
|
||||
|
||||
EncodeOctetString(data, false, tag);
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeOctetString(byte[] value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 0x3e8))
|
||||
{
|
||||
base.EncodeOctetString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1OctetString.Tag.Class, 0x20, Asn1OctetString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i += 0x3e8)
|
||||
{
|
||||
var len = value.Length - i;
|
||||
|
||||
if (len > 0x3e8)
|
||||
{
|
||||
len = 0x3e8;
|
||||
}
|
||||
|
||||
EncodeTagAndLength(Asn1OctetString.Tag, len);
|
||||
Write(value, i, len);
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeStringTag(int nbytes, Asn1Tag tag)
|
||||
{
|
||||
if (nbytes <= 0x3e8)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeTag(tag.Class, 0x20, tag.IdCode);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeStringTag(int nbytes, short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
if (nbytes <= 0x3e8)
|
||||
{
|
||||
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeTag(tagClass, 0x20, tagIdCode);
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeUnivString(int[] value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 250))
|
||||
{
|
||||
base.EncodeUnivString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1UniversalString.Tag.Class, 0x20, Asn1UniversalString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i += 250)
|
||||
{
|
||||
var num2 = value.Length - i;
|
||||
|
||||
if (num2 > 250)
|
||||
{
|
||||
num2 = 250;
|
||||
}
|
||||
|
||||
EncodeTagAndLength(Asn1OctetString.Tag, num2 * 4);
|
||||
|
||||
for (int j = 0; j < num2; j++)
|
||||
{
|
||||
var number = value[j + i];
|
||||
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x18) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x10) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 8) & 0xff));
|
||||
OutputStream.WriteByte((byte)(number & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharRange.cs
vendored
Normal file
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharRange.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1CharRange : Asn1CharSet
|
||||
{
|
||||
private readonly int _lower;
|
||||
private readonly int _upper;
|
||||
|
||||
public Asn1CharRange(int lower, int upper)
|
||||
: base((upper - lower) + 1)
|
||||
{
|
||||
_lower = lower;
|
||||
_upper = upper;
|
||||
}
|
||||
|
||||
public override int MaxValue
|
||||
{
|
||||
get { return _upper; }
|
||||
}
|
||||
|
||||
public override int GetCharAtIndex(int index)
|
||||
{
|
||||
index += _lower;
|
||||
|
||||
if (index > _upper)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
public override int GetCharIndex(int charValue)
|
||||
{
|
||||
var num = charValue - _lower;
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharSet.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharSet.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1CharSet
|
||||
{
|
||||
private readonly int _aBitsPerChar;
|
||||
private readonly int _uBitsPerChar;
|
||||
|
||||
protected internal Asn1CharSet(int nchars)
|
||||
{
|
||||
_uBitsPerChar = Asn1Integer.GetBitCount(nchars - 1);
|
||||
_aBitsPerChar = 1;
|
||||
|
||||
while (_uBitsPerChar > _aBitsPerChar)
|
||||
{
|
||||
_aBitsPerChar = _aBitsPerChar << 1;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int MaxValue { get; }
|
||||
|
||||
public abstract int GetCharAtIndex(int index);
|
||||
|
||||
public abstract int GetCharIndex(int charValue);
|
||||
|
||||
public virtual int GetNumBitsPerChar(bool aligned)
|
||||
{
|
||||
if (!aligned)
|
||||
{
|
||||
return _uBitsPerChar;
|
||||
}
|
||||
|
||||
return _aBitsPerChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
156
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharString.cs
vendored
Normal file
156
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharString.cs
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1CharString : Asn1Type
|
||||
{
|
||||
[NonSerialized]
|
||||
protected StringBuilder StringBuffer;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly short _typeCode;
|
||||
|
||||
[NonSerialized]
|
||||
public string Value;
|
||||
|
||||
|
||||
protected internal Asn1CharString(short typeCode)
|
||||
{
|
||||
Value = new StringBuilder().ToString();
|
||||
_typeCode = typeCode;
|
||||
}
|
||||
|
||||
protected internal Asn1CharString(string data, short typeCode)
|
||||
{
|
||||
Value = data;
|
||||
_typeCode = typeCode;
|
||||
}
|
||||
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return Value.Length; }
|
||||
}
|
||||
|
||||
protected virtual void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
|
||||
{
|
||||
int num2;
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, tag) : implicitLength;
|
||||
var num3 = elemLength;
|
||||
var num4 = 0;
|
||||
|
||||
if (StringBuffer == null)
|
||||
{
|
||||
StringBuffer = new StringBuilder();
|
||||
}
|
||||
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
if (num3 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
StringBuffer.Length = num3;
|
||||
|
||||
while (num3 > 0)
|
||||
{
|
||||
num2 = buffer.Read();
|
||||
|
||||
if (num2 == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
StringBuffer[num4++] = (char)num2;
|
||||
num3--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var capacity = 0;
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num5 = MatchTag(buffer, Asn1OctetString.Tag);
|
||||
|
||||
if (num5 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
capacity += num5;
|
||||
StringBuffer.EnsureCapacity(capacity);
|
||||
|
||||
while (num5 > 0)
|
||||
{
|
||||
num2 = buffer.Read();
|
||||
|
||||
if (num2 == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
StringBuffer.Append((char)num2);
|
||||
num5--;
|
||||
}
|
||||
}
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
Value = StringBuffer.ToString();
|
||||
buffer.TypeCode = (short)tag.IdCode;
|
||||
}
|
||||
|
||||
protected virtual int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
var length = Value.Length;
|
||||
buffer.Copy(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1CharString;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(str.Value);
|
||||
}
|
||||
|
||||
public bool Equals(string value)
|
||||
{
|
||||
return Value.Equals(value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Choice.cs
vendored
Normal file
55
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Choice.cs
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Choice : Asn1Type
|
||||
{
|
||||
[NonSerialized]
|
||||
private int _choiceId;
|
||||
|
||||
[NonSerialized]
|
||||
protected Asn1Type Element;
|
||||
|
||||
|
||||
public virtual int ChoiceId => _choiceId;
|
||||
|
||||
public abstract string ElemName { get; }
|
||||
|
||||
|
||||
public virtual Asn1Type GetElement()
|
||||
{
|
||||
return Element;
|
||||
}
|
||||
|
||||
public virtual void SetElement(int choiceId, Asn1Type element)
|
||||
{
|
||||
_choiceId = choiceId;
|
||||
|
||||
Element = element;
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var choice = value as Asn1Choice;
|
||||
|
||||
if (choice == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_choiceId != choice._choiceId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Element.Equals(choice.Element);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Element?.GetHashCode() ?? base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ChoiceExt.cs
vendored
Normal file
23
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ChoiceExt.cs
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ChoiceExt : Asn1OpenType
|
||||
{
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
base.Decode(buffer, false, 0);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return base.Encode(buffer, false);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
base.Encode(outs, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
326
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1DecodeBuffer.cs
vendored
Normal file
326
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1DecodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1DecodeBuffer : Asn1MessageBuffer
|
||||
{
|
||||
private readonly ArrayList _captureBufferList;
|
||||
private int _byteCount;
|
||||
private Stream _inputStream;
|
||||
private long _markedPosition;
|
||||
private ArrayList _namedEventHandlerList;
|
||||
private int _savedByteCount;
|
||||
private short _typeCode;
|
||||
private int[] _oidBuffer;
|
||||
|
||||
protected Asn1DecodeBuffer(byte[] msgdata)
|
||||
{
|
||||
_namedEventHandlerList = new ArrayList();
|
||||
_captureBufferList = new ArrayList(5);
|
||||
|
||||
SetInputStream(msgdata, 0, msgdata.Length);
|
||||
}
|
||||
|
||||
protected Asn1DecodeBuffer(Stream inputStream)
|
||||
{
|
||||
_namedEventHandlerList = new ArrayList();
|
||||
_captureBufferList = new ArrayList(5);
|
||||
|
||||
_inputStream = inputStream.CanSeek ? inputStream : new BufferedStream(inputStream);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual int ByteCount
|
||||
{
|
||||
get { return _byteCount; }
|
||||
}
|
||||
|
||||
public virtual Asn1DecodeBuffer EventHandlerList
|
||||
{
|
||||
set { _namedEventHandlerList = value._namedEventHandlerList; }
|
||||
}
|
||||
|
||||
public virtual short TypeCode
|
||||
{
|
||||
set { _typeCode = value; }
|
||||
}
|
||||
|
||||
public virtual void AddCaptureBuffer(MemoryStream buffer)
|
||||
{
|
||||
_captureBufferList.Add(buffer);
|
||||
}
|
||||
|
||||
public virtual void AddNamedEventHandler(IAsn1NamedEventHandler handler)
|
||||
{
|
||||
_namedEventHandlerList.Add(handler);
|
||||
}
|
||||
|
||||
public virtual void Capture(int nbytes)
|
||||
{
|
||||
for (var i = 0; i < nbytes; i++)
|
||||
{
|
||||
var num = _inputStream.ReadByte();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
foreach (MemoryStream s in _captureBufferList)
|
||||
{
|
||||
s.WriteByte((byte)num);
|
||||
}
|
||||
|
||||
_byteCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual long DecodeIntValue(int length, bool signExtend)
|
||||
{
|
||||
return Asn1RunTime.DecodeIntValue(this, length, signExtend);
|
||||
}
|
||||
|
||||
public virtual int[] DecodeOidContents(int llen)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
if (_oidBuffer == null)
|
||||
{
|
||||
_oidBuffer = new int[0x80];
|
||||
}
|
||||
|
||||
while (llen > 0)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (index >= 0x80)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
_oidBuffer[index] = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = ReadByte();
|
||||
_oidBuffer[index] = (_oidBuffer[index] * 0x80) + (num & 0x7f);
|
||||
llen--;
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
var num3 = _oidBuffer[0];
|
||||
|
||||
_oidBuffer[0] = ((num3 / 40) >= 2) ? 2 : (num3 / 40);
|
||||
_oidBuffer[1] = (_oidBuffer[0] == 2) ? (num3 - 80) : (num3 % 40);
|
||||
|
||||
index = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (llen != 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
var destinationArray = new int[index];
|
||||
Array.Copy(_oidBuffer, 0, destinationArray, 0, index);
|
||||
return destinationArray;
|
||||
}
|
||||
|
||||
public virtual int[] DecodeRelOidContents(int llen)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
if (_oidBuffer == null)
|
||||
{
|
||||
_oidBuffer = new int[0x80];
|
||||
}
|
||||
|
||||
while (llen > 0)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (index >= 0x80)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
_oidBuffer[index] = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = ReadByte();
|
||||
_oidBuffer[index] = (_oidBuffer[index] * 0x80) + (num & 0x7f);
|
||||
llen--;
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if (llen != 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
var destinationArray = new int[index];
|
||||
Array.Copy(_oidBuffer, 0, destinationArray, 0, index);
|
||||
return destinationArray;
|
||||
}
|
||||
|
||||
public override Stream GetInputStream()
|
||||
{
|
||||
return _inputStream;
|
||||
}
|
||||
|
||||
public virtual void HexDump()
|
||||
{
|
||||
HexDump(_inputStream);
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
_byteCount = 0;
|
||||
_markedPosition = 0L;
|
||||
_savedByteCount = 0;
|
||||
}
|
||||
|
||||
public virtual void InvokeCharacters(string svalue)
|
||||
{
|
||||
var enumerator = _namedEventHandlerList.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((IAsn1NamedEventHandler)enumerator.Current).Characters(svalue, _typeCode);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void InvokeEndElement(string name, int index)
|
||||
{
|
||||
var enumerator = _namedEventHandlerList.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((IAsn1NamedEventHandler)enumerator.Current).EndElement(name, index);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void InvokeStartElement(string name, int index)
|
||||
{
|
||||
var enumerator = _namedEventHandlerList.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((IAsn1NamedEventHandler)enumerator.Current).StartElement(name, index);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Mark()
|
||||
{
|
||||
_savedByteCount = _byteCount;
|
||||
_markedPosition = _inputStream.Position;
|
||||
}
|
||||
|
||||
public virtual int Read()
|
||||
{
|
||||
var num = _inputStream.ReadByte();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
foreach (MemoryStream s in _captureBufferList)
|
||||
{
|
||||
s.WriteByte((byte)num);
|
||||
}
|
||||
|
||||
_byteCount++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual void Read(byte[] buffer)
|
||||
{
|
||||
Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public virtual void Read(byte[] buffer, int offset, int nbytes)
|
||||
{
|
||||
var count = nbytes;
|
||||
var num3 = offset;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
var num = _inputStream.Read(buffer, num3, count);
|
||||
|
||||
if (num <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num3 += num;
|
||||
count -= num;
|
||||
}
|
||||
|
||||
foreach (MemoryStream s in _captureBufferList)
|
||||
{
|
||||
s.Write(buffer, offset, nbytes);
|
||||
}
|
||||
|
||||
_byteCount += nbytes;
|
||||
}
|
||||
|
||||
public abstract int ReadByte();
|
||||
|
||||
public virtual void RemoveCaptureBuffer(MemoryStream buffer)
|
||||
{
|
||||
for (var i = 0; i < _captureBufferList.Count; i++)
|
||||
{
|
||||
if (buffer == _captureBufferList[i])
|
||||
{
|
||||
_captureBufferList.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
try
|
||||
{
|
||||
_inputStream.Position = _markedPosition;
|
||||
_byteCount = _savedByteCount;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetInputStream(byte[] msgdata, int offset, int length)
|
||||
{
|
||||
_inputStream = new MemoryStream(msgdata, offset, length);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual long Skip(long nbytes)
|
||||
{
|
||||
var inputStream = _inputStream;
|
||||
var position = inputStream.Position;
|
||||
|
||||
return (inputStream.Seek(nbytes, SeekOrigin.Current) - position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DerDecodeBuffer : Asn1BerDecodeBuffer
|
||||
{
|
||||
public Asn1DerDecodeBuffer(byte[] msgdata)
|
||||
: base(msgdata)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1DerDecodeBuffer(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DerEncodeBuffer : Asn1BerEncodeBuffer
|
||||
{
|
||||
public Asn1DerEncodeBuffer()
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
|
||||
public Asn1DerEncodeBuffer(int sizeIncrement)
|
||||
: base(sizeIncrement)
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DerInputStream : Asn1DerDecodeBuffer, IAsn1InputStream
|
||||
{
|
||||
public Asn1DerInputStream(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Available()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
var num = inputStream.Length - inputStream.Position;
|
||||
return (int)num;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
inputStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool MarkSupported()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
return ((inputStream != null) && inputStream.CanSeek);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DiscreteCharSet : Asn1CharSet
|
||||
{
|
||||
private readonly int[] _charSet;
|
||||
|
||||
public Asn1DiscreteCharSet(string charSet)
|
||||
: base(charSet.Length)
|
||||
{
|
||||
_charSet = new int[charSet.Length];
|
||||
|
||||
for (var i = 0; i < _charSet.Length; i++)
|
||||
{
|
||||
_charSet[i] = charSet[i];
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1DiscreteCharSet(int[] charSet)
|
||||
: base(charSet.Length)
|
||||
{
|
||||
_charSet = charSet;
|
||||
}
|
||||
|
||||
public override int MaxValue
|
||||
{
|
||||
get { return _charSet[_charSet.Length - 1]; }
|
||||
}
|
||||
|
||||
public override int GetCharAtIndex(int index)
|
||||
{
|
||||
if (index >= _charSet.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index);
|
||||
}
|
||||
|
||||
return _charSet[index];
|
||||
}
|
||||
|
||||
public override int GetCharIndex(int charValue)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
while ((index < _charSet.Length) && (_charSet[index] != charValue))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= _charSet.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
84
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1EncodeBuffer.cs
vendored
Normal file
84
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1EncodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1EncodeBuffer : Asn1MessageBuffer
|
||||
{
|
||||
public const int DefaultSizeIncrement = 0x400;
|
||||
|
||||
protected byte[] Data;
|
||||
protected int ByteIndex;
|
||||
protected int SizeIncrement;
|
||||
|
||||
protected Asn1EncodeBuffer()
|
||||
{
|
||||
InitBuffer(DefaultSizeIncrement);
|
||||
}
|
||||
|
||||
protected Asn1EncodeBuffer(int sizeIncrement)
|
||||
{
|
||||
if (sizeIncrement == 0)
|
||||
{
|
||||
sizeIncrement = DefaultSizeIncrement;
|
||||
}
|
||||
|
||||
InitBuffer(sizeIncrement);
|
||||
}
|
||||
|
||||
public abstract byte[] MsgCopy { get; }
|
||||
|
||||
public abstract int MsgLength { get; }
|
||||
|
||||
public virtual void BinDump(string varName)
|
||||
{
|
||||
var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding)
|
||||
{
|
||||
AutoFlush = true
|
||||
};
|
||||
|
||||
BinDump(outs, varName);
|
||||
}
|
||||
|
||||
public abstract void BinDump(StreamWriter outs, string varName);
|
||||
|
||||
protected internal virtual void CheckSize(int bytesRequired)
|
||||
{
|
||||
if ((ByteIndex + bytesRequired) > Data.Length)
|
||||
{
|
||||
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
|
||||
var num2 = num * SizeIncrement;
|
||||
var destinationArray = new byte[Data.Length + num2];
|
||||
|
||||
Array.Copy(Data, 0, destinationArray, 0, ByteIndex + 1);
|
||||
|
||||
Data = destinationArray;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void Copy(byte value);
|
||||
|
||||
public abstract void Copy(byte[] value);
|
||||
|
||||
public virtual void HexDump()
|
||||
{
|
||||
HexDump(GetInputStream());
|
||||
}
|
||||
|
||||
public virtual void HexDump(StreamWriter outs)
|
||||
{
|
||||
HexDump(GetInputStream(), outs);
|
||||
}
|
||||
|
||||
protected virtual void InitBuffer(int sizeIncrement)
|
||||
{
|
||||
SizeIncrement = sizeIncrement;
|
||||
Data = new byte[SizeIncrement];
|
||||
ByteIndex = 0;
|
||||
}
|
||||
|
||||
public abstract void Reset();
|
||||
|
||||
public abstract void Write(Stream outs);
|
||||
}
|
||||
}
|
||||
80
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Enumerated.cs
vendored
Normal file
80
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Enumerated.cs
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Enumerated : Asn1Type
|
||||
{
|
||||
public const int Undefined = -999;
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, EnumeratedTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public int Value;
|
||||
|
||||
public Asn1Enumerated()
|
||||
{
|
||||
Value = Undefined;
|
||||
}
|
||||
|
||||
public Asn1Enumerated(int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
Value = (int)Asn1RunTime.DecodeIntValue(buffer, length, true);
|
||||
buffer.TypeCode = EnumeratedTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = buffer.EncodeIntValue(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeIntValue(Value, true);
|
||||
}
|
||||
|
||||
public virtual bool Equals(int value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var enumerated = value as Asn1Enumerated;
|
||||
|
||||
return (enumerated != null && Value == enumerated.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public virtual int ParseValue(string value)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralString.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralString.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1GeneralString : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralStringTypeCode);
|
||||
|
||||
public Asn1GeneralString()
|
||||
: base(GeneralStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralString(string data)
|
||||
: base(data, GeneralStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
344
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralizedTime.cs
vendored
Normal file
344
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralizedTime.cs
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1GeneralizedTime : Asn1Time
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralTimeTypeCode);
|
||||
|
||||
public Asn1GeneralizedTime()
|
||||
: base(GeneralTimeTypeCode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(bool useDerRules)
|
||||
: base(GeneralTimeTypeCode, useDerRules)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(string data)
|
||||
: base(data, GeneralTimeTypeCode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(string data, bool useDerRules)
|
||||
: base(data, GeneralTimeTypeCode, useDerRules)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Century
|
||||
{
|
||||
get
|
||||
{
|
||||
var yearValue = Year;
|
||||
|
||||
if (yearValue < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, yearValue);
|
||||
}
|
||||
|
||||
return (yearValue / 100);
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 0x63))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidCenturyValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
YearValue = (value * 100) + (YearValue % 100);
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CompileString()
|
||||
{
|
||||
int minuteValue;
|
||||
|
||||
if (((YearValue < 0) || (MonthValue <= 0)) || ((DayValue <= 0) || (HourValue < 0)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Value = "";
|
||||
|
||||
if (StringBuffer == null)
|
||||
{
|
||||
StringBuffer = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuffer.Length = 0;
|
||||
}
|
||||
|
||||
if ((DerRules || UtcFlag) && ((DiffHourValue != 0) || (DiffMinValue != 0)))
|
||||
{
|
||||
var time = GetTime();
|
||||
time.AddMinutes(-DiffMinValue);
|
||||
time.AddHours(-DiffHourValue);
|
||||
|
||||
PutInteger(4, time.Year);
|
||||
PutInteger(2, time.Month);
|
||||
PutInteger(2, time.Day);
|
||||
PutInteger(2, time.Hour);
|
||||
|
||||
minuteValue = time.Minute;
|
||||
}
|
||||
else
|
||||
{
|
||||
PutInteger(4, YearValue);
|
||||
PutInteger(2, MonthValue);
|
||||
PutInteger(2, DayValue);
|
||||
PutInteger(2, HourValue);
|
||||
|
||||
minuteValue = MinuteValue;
|
||||
}
|
||||
|
||||
if ((DerRules || (minuteValue > 0)) || ((SecondValue > 0) || (SecFraction.Length > 0)))
|
||||
{
|
||||
PutInteger(2, minuteValue);
|
||||
|
||||
if ((DerRules || (SecondValue > 0)) || (SecFraction.Length > 0))
|
||||
{
|
||||
PutInteger(2, SecondValue);
|
||||
|
||||
if (SecFraction.Length > 0)
|
||||
{
|
||||
StringBuffer.Append('.');
|
||||
StringBuffer.Append(SecFraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DerRules || UtcFlag)
|
||||
{
|
||||
StringBuffer.Append('Z');
|
||||
}
|
||||
else if ((DiffHourValue != 0) || (DiffMinValue != 0))
|
||||
{
|
||||
StringBuffer.Append((DiffHourValue > 0) ? '+' : '-');
|
||||
|
||||
if (DiffMinValue != 0)
|
||||
{
|
||||
PutInteger(2, Math.Abs(DiffHourValue));
|
||||
PutInteger(2, Math.Abs(DiffMinValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
PutInteger(2, Math.Abs(DiffHourValue));
|
||||
}
|
||||
}
|
||||
|
||||
Value = StringBuffer.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
Encode(outs, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void ParseString(string data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw ExceptionUtility.ArgumentNull("data");
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
var off = new IntHolder(0);
|
||||
|
||||
try
|
||||
{
|
||||
YearValue = ParseInt(data, off, 4);
|
||||
MonthValue = ParseInt(data, off, 2);
|
||||
DayValue = ParseInt(data, off, 2);
|
||||
|
||||
if (YearValue < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
|
||||
}
|
||||
|
||||
if ((MonthValue < 1) || (MonthValue > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, MonthValue);
|
||||
}
|
||||
|
||||
int num = DaysInMonth[MonthValue];
|
||||
|
||||
if (((MonthValue == 2) && ((YearValue % 4) == 0)) && (((YearValue % 100) != 0) || ((YearValue % 400) == 0)))
|
||||
{
|
||||
num++;
|
||||
}
|
||||
|
||||
if ((DayValue < 1) || (DayValue > num))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValue, DayValue);
|
||||
}
|
||||
|
||||
var num2 = 0;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1HoursExpected);
|
||||
}
|
||||
|
||||
HourValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
MinuteValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
SecondValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((num2 >= 1) && ((HourValue < 0) || (HourValue > 0x17)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, HourValue);
|
||||
}
|
||||
|
||||
if ((num2 >= 2) && ((MinuteValue < 0) || (MinuteValue > 0x3b)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, MinuteValue);
|
||||
}
|
||||
|
||||
if ((num2 == 3) && ((SecondValue < 0) || (SecondValue > 0x3b)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, SecondValue);
|
||||
}
|
||||
|
||||
var ch = CharAt(data, off.Value);
|
||||
|
||||
if (DerRules && (ch == ','))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDecimalMark);
|
||||
}
|
||||
|
||||
if ((ch == '.') || (ch == ','))
|
||||
{
|
||||
off.Value++;
|
||||
|
||||
if (num2 != 3)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
|
||||
}
|
||||
|
||||
var length = 0;
|
||||
|
||||
while (char.IsDigit(CharAt(data, off.Value + length)))
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
|
||||
}
|
||||
|
||||
SecFraction = data.Substring(off.Value, length);
|
||||
off.Value += length;
|
||||
}
|
||||
|
||||
if (CharAt(data, off.Value) == 'Z')
|
||||
{
|
||||
off.Value++;
|
||||
UtcFlag = true;
|
||||
|
||||
if (off.Value != data.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedValuesAtEndOfString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DerRules)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedZoneOffset);
|
||||
}
|
||||
|
||||
UtcFlag = false;
|
||||
|
||||
var ch2 = CharAt(data, off.Value);
|
||||
|
||||
switch (ch2)
|
||||
{
|
||||
case '-':
|
||||
case '+':
|
||||
off.Value++;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHour);
|
||||
}
|
||||
|
||||
DiffHourValue = ParseInt(data, off, 2);
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
DiffMinValue = ParseInt(data, off, 2);
|
||||
}
|
||||
|
||||
if ((DiffHourValue < 0) || (DiffHourValue > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, DiffHourValue);
|
||||
}
|
||||
|
||||
if ((DiffMinValue < 0) || (DiffMinValue > 0x3b))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, DiffMinValue);
|
||||
}
|
||||
|
||||
if (ch2 == '-')
|
||||
{
|
||||
DiffHourValue = -DiffHourValue;
|
||||
DiffMinValue = -DiffMinValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Parsed = true;
|
||||
|
||||
if (data != Value)
|
||||
{
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidNumberFormat);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GraphicString.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GraphicString.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1GraphicString : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GraphicStringTypeCode);
|
||||
|
||||
public Asn1GraphicString()
|
||||
: base(GraphicStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GraphicString(string data)
|
||||
: base(data, GraphicStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(base.Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Ia5String.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Ia5String.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Ia5String : Asn18BitCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Ia5StringTypeCode);
|
||||
|
||||
public Asn1Ia5String()
|
||||
: base(Ia5StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1Ia5String(string data)
|
||||
: base(data, Ia5StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
91
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Integer.cs
vendored
Normal file
91
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Integer.cs
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Integer : Asn1Type
|
||||
{
|
||||
public const int SizeOfInt = 4;
|
||||
public const int SizeOfLong = 8;
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public long Value;
|
||||
|
||||
public Asn1Integer()
|
||||
{
|
||||
Value = 0L;
|
||||
}
|
||||
|
||||
public Asn1Integer(long value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
Value = Asn1RunTime.DecodeIntValue(buffer, length, true);
|
||||
buffer.TypeCode = BigIntegerTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = buffer.EncodeIntValue(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeIntValue(Value, true);
|
||||
}
|
||||
|
||||
public virtual bool Equals(long value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var integer = value as Asn1Integer;
|
||||
|
||||
if (integer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Value == integer.Value);
|
||||
}
|
||||
|
||||
public virtual int GetBitCount()
|
||||
{
|
||||
return Asn1RunTime.GetLongBitCount(Value);
|
||||
}
|
||||
|
||||
public static int GetBitCount(long ivalue)
|
||||
{
|
||||
return Asn1RunTime.GetLongBitCount(ivalue);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Convert.ToString(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1MessageBuffer.cs
vendored
Normal file
24
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1MessageBuffer.cs
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1MessageBuffer
|
||||
{
|
||||
public abstract Stream GetInputStream();
|
||||
|
||||
public static void HexDump(Stream ins)
|
||||
{
|
||||
var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding)
|
||||
{
|
||||
AutoFlush = true
|
||||
};
|
||||
|
||||
HexDump(ins, outs);
|
||||
}
|
||||
|
||||
public static void HexDump(Stream ins, StreamWriter outs)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
48
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Null.cs
vendored
Normal file
48
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Null.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Null : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NullTypeCode);
|
||||
public static readonly Asn1Null NullValue = new Asn1Null();
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
MatchTag(buffer, Tag);
|
||||
}
|
||||
|
||||
buffer.TypeCode = NullTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(0);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1NumericString.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1NumericString.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1NumericString : Asn18BitCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NumericStringTypeCode);
|
||||
|
||||
public Asn1NumericString()
|
||||
: base(NumericStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1NumericString(string data)
|
||||
: base(data, NumericStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ObjectDescriptor : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectDescriptorTypeCode);
|
||||
|
||||
public Asn1ObjectDescriptor()
|
||||
: base(ObjectDescriptorTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1ObjectDescriptor(string data)
|
||||
: base(data, ObjectDescriptorTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ObjectIdentifier.cs
vendored
Normal file
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ObjectIdentifier.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ObjectIdentifier : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectIdentifierTypeCode);
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected OidValue OidValue;
|
||||
|
||||
public OidValue Oid => OidValue;
|
||||
|
||||
|
||||
public Asn1ObjectIdentifier()
|
||||
{
|
||||
OidValue = null;
|
||||
}
|
||||
|
||||
public Asn1ObjectIdentifier(OidValue oidValue)
|
||||
{
|
||||
OidValue = oidValue;
|
||||
}
|
||||
|
||||
|
||||
public static Asn1ObjectIdentifier FromString(string value)
|
||||
{
|
||||
return string.IsNullOrEmpty(value) ? null : new Asn1ObjectIdentifier(OidValue.FromString(value));
|
||||
}
|
||||
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
OidValue = OidValue.FromArray(buffer.DecodeOidContents(len));
|
||||
buffer.TypeCode = ObjectIdentifierTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
var len = 0;
|
||||
|
||||
for (var i = OidValue.Items.Length - 1; i >= 1; i--)
|
||||
{
|
||||
len += buffer.EncodeIdentifier((i == 1) ? ((OidValue.Items[0] * 40) + OidValue.Items[1]) : OidValue.Items[i]);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
var len = 1;
|
||||
|
||||
for (var i = 2; i < OidValue.Items.Length; i++)
|
||||
{
|
||||
len += Asn1RunTime.GetIdentBytesCount(OidValue.Items[i]);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(len);
|
||||
var ident = (OidValue.Items[0] * 40) + OidValue.Items[1];
|
||||
outs.EncodeIdentifier(ident);
|
||||
|
||||
for (var i = 2; i < OidValue.Items.Length; i++)
|
||||
{
|
||||
outs.EncodeIdentifier(OidValue.Items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj is Asn1ObjectIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var other = (Asn1ObjectIdentifier)obj;
|
||||
|
||||
if (OidValue == other.OidValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (OidValue == null || other.OidValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OidValue.Equals(other.OidValue);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return OidValue?.GetHashCode() ?? base.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return OidValue?.ToString() ?? base.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
235
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OctetString.cs
vendored
Normal file
235
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OctetString.cs
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1OctetString : Asn1Type, IComparable
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, OctetStringTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public byte[] Value;
|
||||
|
||||
public Asn1OctetString()
|
||||
{
|
||||
Value = null;
|
||||
}
|
||||
|
||||
public Asn1OctetString(byte[] data)
|
||||
{
|
||||
Value = data;
|
||||
}
|
||||
|
||||
public Asn1OctetString(string value)
|
||||
{
|
||||
Value = string.IsNullOrEmpty(value) ? new byte[0] : Asn1Value.ParseString(value);
|
||||
}
|
||||
|
||||
public Asn1OctetString(byte[] data, int offset, int nbytes)
|
||||
{
|
||||
Value = new byte[nbytes];
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
Array.Copy(data, offset, Value, 0, nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return Value.Length; }
|
||||
}
|
||||
|
||||
public virtual int CompareTo(object octstr)
|
||||
{
|
||||
var value = ((Asn1OctetString)octstr).Value;
|
||||
var num = (Value.Length < value.Length) ? Value.Length : value.Length;
|
||||
|
||||
for (var i = 0; i < num; i++)
|
||||
{
|
||||
var num2 = Value[i] & 0xff;
|
||||
var num3 = value[i] & 0xff;
|
||||
|
||||
if (num2 < num3)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (num2 > num3)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Value.Length == value.Length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Value.Length < value.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void AllocByteArray(int nbytes)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new byte[nbytes];
|
||||
}
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
if (elemLength < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
Value = new byte[elemLength];
|
||||
|
||||
if (elemLength != 0)
|
||||
{
|
||||
buffer.Read(Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var nbytes = 0;
|
||||
var offset = 0;
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num2 = MatchTag(buffer, Tag);
|
||||
|
||||
if (num2 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
nbytes += num2;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
Value = new byte[nbytes];
|
||||
}
|
||||
else
|
||||
{
|
||||
ReAllocByteArray(nbytes);
|
||||
}
|
||||
|
||||
buffer.Read(Value, offset, num2);
|
||||
offset = nbytes;
|
||||
}
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = OctetStringTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new byte[0];
|
||||
}
|
||||
|
||||
var length = Value.Length;
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
buffer.Copy(Value);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeOctetString(Value, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public bool Equals(byte[] value)
|
||||
{
|
||||
if (value.Length != Value.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
if (value[i] != Value[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1OctetString;
|
||||
|
||||
return (str != null) && Equals(str.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
private void ReAllocByteArray(int nbytes)
|
||||
{
|
||||
var value = Value;
|
||||
Value = new byte[nbytes];
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
Array.Copy(value, 0, Value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Stream ToInputStream()
|
||||
{
|
||||
return new MemoryStream(Value, 0, Value.Length);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
if (Value != null)
|
||||
{
|
||||
foreach (var b in Value)
|
||||
{
|
||||
str = str + Asn1Util.ToHexString(b);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
86
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenExt.cs
vendored
Normal file
86
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenExt.cs
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1OpenExt : Asn1Type
|
||||
{
|
||||
[NonSerialized]
|
||||
public ArrayList Value = new ArrayList();
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
DecodeComponent(buffer);
|
||||
}
|
||||
|
||||
public virtual void DecodeComponent(Asn1BerDecodeBuffer buffer)
|
||||
{
|
||||
var type = new Asn1OpenType();
|
||||
type.Decode(buffer, false, 0);
|
||||
Value.Add(type);
|
||||
}
|
||||
|
||||
public virtual void DecodeEventComponent(Asn1BerDecodeBuffer buffer)
|
||||
{
|
||||
buffer.InvokeStartElement("...", -1);
|
||||
|
||||
var type = new Asn1OpenType();
|
||||
type.Decode(buffer, false, 0);
|
||||
|
||||
Value.Add(type);
|
||||
|
||||
buffer.InvokeCharacters(type.ToString());
|
||||
buffer.InvokeEndElement("...", -1);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var num = 0;
|
||||
|
||||
for (var i = Value.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var type = (Asn1OpenType)Value[i];
|
||||
num += type.Encode(buffer, false);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
foreach (Asn1OpenType type in Value)
|
||||
{
|
||||
if (type != null)
|
||||
{
|
||||
type.Encode(outs, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
return "<null>";
|
||||
}
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Value.Count; i++)
|
||||
{
|
||||
var type = (Asn1OpenType)Value[i];
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
builder.Append(", ");
|
||||
}
|
||||
|
||||
builder.Append(type);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
103
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenType.cs
vendored
Normal file
103
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenType.cs
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1OpenType : Asn1OctetString
|
||||
{
|
||||
private const string EncodedDataMessage = "ENCODED DATA";
|
||||
|
||||
[NonSerialized]
|
||||
private readonly Asn1EncodeBuffer _encodeBuffer;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly int _length;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly bool _textEncoding;
|
||||
|
||||
|
||||
public Asn1OpenType()
|
||||
{
|
||||
_length = 0;
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public Asn1OpenType(byte[] data)
|
||||
: base(data)
|
||||
{
|
||||
_length = 0;
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public Asn1OpenType(Asn1EncodeBuffer buffer)
|
||||
{
|
||||
if (buffer is Asn1BerEncodeBuffer)
|
||||
{
|
||||
_length = buffer.MsgLength;
|
||||
_encodeBuffer = buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = buffer.MsgCopy;
|
||||
}
|
||||
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public Asn1OpenType(byte[] data, int offset, int nbytes)
|
||||
: base(data, offset, nbytes)
|
||||
{
|
||||
_length = 0;
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Value = buffer.DecodeOpenType();
|
||||
buffer.TypeCode = OpenTypeTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
return base.Encode(buffer, false);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (Value != null)
|
||||
{
|
||||
outs.Write(Value);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (_textEncoding ? Encoding.UTF8.GetString(Value, 0, Value.Length) : base.ToString());
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (_encodeBuffer != null)
|
||||
{
|
||||
return _encodeBuffer.ToString();
|
||||
}
|
||||
|
||||
return EncodedDataMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OutputStream.cs
vendored
Normal file
87
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OutputStream.cs
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1OutputStream : Stream
|
||||
{
|
||||
protected readonly Stream OutputStream;
|
||||
|
||||
public Asn1OutputStream(Stream outputStream)
|
||||
{
|
||||
OutputStream = outputStream;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return OutputStream.CanSeek; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return OutputStream.CanWrite; }
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return OutputStream.Length; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get { return OutputStream.Position; }
|
||||
set { OutputStream.Position = value; }
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
OutputStream.Close();
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
OutputStream.Flush();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw ExceptionUtility.NotSupported(Resources.Asn1ReadOutputStreamNotSupported);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
return OutputStream.Seek(offset, origin);
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
OutputStream.SetLength(value);
|
||||
}
|
||||
|
||||
public virtual void Write(byte[] b)
|
||||
{
|
||||
OutputStream.Write(b, 0, b.Length);
|
||||
}
|
||||
|
||||
public override void Write(byte[] b, int off, int len)
|
||||
{
|
||||
OutputStream.Write(b, off, len);
|
||||
}
|
||||
|
||||
public override void WriteByte(byte b)
|
||||
{
|
||||
OutputStream.WriteByte(b);
|
||||
}
|
||||
|
||||
public virtual void WriteByte(int b)
|
||||
{
|
||||
OutputStream.WriteByte((byte)b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1PrintableString : Asn18BitCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, PrintableStringTypeCode);
|
||||
|
||||
public Asn1PrintableString()
|
||||
: base(PrintableStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1PrintableString(string data)
|
||||
: base(data, PrintableStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
371
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Real.cs
vendored
Normal file
371
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Real.cs
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Real : Asn1Type
|
||||
{
|
||||
private const int MinusInfinity = 0x41;
|
||||
private const int PlusInfinity = 0x40;
|
||||
private const int RealBase2 = 0;
|
||||
private const int RealBase8 = 0x10;
|
||||
private const int RealBase16 = 0x20;
|
||||
private const int RealBaseMask = 0x30;
|
||||
private const int RealBinary = 0x80;
|
||||
private const int RealExplen1 = 0;
|
||||
private const int RealExplen2 = 1;
|
||||
private const int RealExplen3 = 2;
|
||||
private const int RealExplenLong = 3;
|
||||
private const int RealExplenMask = 3;
|
||||
private const int RealFactorMask = 12;
|
||||
private const int RealIso6093Mask = 0x3f;
|
||||
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RealTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public double Value;
|
||||
|
||||
public Asn1Real()
|
||||
{
|
||||
Value = 0.0;
|
||||
}
|
||||
|
||||
public Asn1Real(double value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
Value = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var num2 = buffer.ReadByte();
|
||||
|
||||
if (length == 1)
|
||||
{
|
||||
switch (num2)
|
||||
{
|
||||
case PlusInfinity:
|
||||
Value = double.PositiveInfinity;
|
||||
return;
|
||||
|
||||
case MinusInfinity:
|
||||
Value = double.NegativeInfinity;
|
||||
return;
|
||||
}
|
||||
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
length--;
|
||||
|
||||
if ((num2 & RealBinary) == 0)
|
||||
{
|
||||
var num8 = length;
|
||||
var num9 = 0;
|
||||
|
||||
var builder = new StringBuilder { Length = num8 };
|
||||
|
||||
while (num8 > 0)
|
||||
{
|
||||
var num7 = buffer.Read();
|
||||
|
||||
if (num7 == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
builder[num9++] = (char)num7;
|
||||
num8--;
|
||||
}
|
||||
|
||||
var num10 = num2 & RealIso6093Mask;
|
||||
var num11 = 0;
|
||||
|
||||
for (var i = 0; i < builder.Length; i++)
|
||||
{
|
||||
var ch = builder[i];
|
||||
|
||||
if ((num10 >= 2) && (ch == ','))
|
||||
{
|
||||
builder[i] = '.';
|
||||
num11++;
|
||||
}
|
||||
else if (((num10 >= 1) && (((ch >= '0') && (ch <= '9')) || ((ch == '+') || (ch == '-')))) || (((num10 >= 2) && (ch == '.')) || ((num10 == 3) && ((ch == 'E') || (ch == 'e')))))
|
||||
{
|
||||
num11++;
|
||||
}
|
||||
else if ((num11 != 0) || (ch != ' '))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Value = double.Parse(builder.ToString());
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int num6;
|
||||
int num3;
|
||||
|
||||
switch ((num2 & RealExplenMask))
|
||||
{
|
||||
case RealExplen1:
|
||||
num3 = 1;
|
||||
break;
|
||||
|
||||
case RealExplen2:
|
||||
num3 = 2;
|
||||
break;
|
||||
|
||||
case RealExplen3:
|
||||
num3 = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
num3 = buffer.ReadByte();
|
||||
length--;
|
||||
break;
|
||||
}
|
||||
|
||||
var num4 = (int)Asn1RunTime.DecodeIntValue(buffer, num3, true);
|
||||
length -= num3;
|
||||
|
||||
var num5 = Asn1RunTime.DecodeIntValue(buffer, length, false) * (1L << ((num2 & RealFactorMask) >> 2));
|
||||
|
||||
switch ((num2 & RealBaseMask))
|
||||
{
|
||||
case RealBase2:
|
||||
num6 = 2;
|
||||
break;
|
||||
|
||||
case RealBase8:
|
||||
num6 = 8;
|
||||
break;
|
||||
|
||||
case RealBase16:
|
||||
num6 = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
Value = num5 * Math.Pow(num6, num4);
|
||||
|
||||
if ((num2 & PlusInfinity) != 0)
|
||||
{
|
||||
Value = -Value;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = RealTypeCode;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
if (double.IsNegativeInfinity(Value))
|
||||
{
|
||||
len = buffer.EncodeIntValue(MinusInfinity);
|
||||
}
|
||||
else if (double.IsPositiveInfinity(Value))
|
||||
{
|
||||
len = buffer.EncodeIntValue(PlusInfinity);
|
||||
}
|
||||
|
||||
else if (Value != 0.0)
|
||||
{
|
||||
var num2 = BitConverter.DoubleToInt64Bits(Value);
|
||||
var num3 = ((num2 >> RealIso6093Mask) == 0L) ? 1 : -1;
|
||||
var num4 = ((int)((num2 >> 0x34) & 0x7ffL)) - 0x433;
|
||||
var w = (num4 == 0) ? ((num2 & 0xfffffffffffffL) << 1) : ((num2 & 0xfffffffffffffL) | 0x10000000000000L);
|
||||
|
||||
if (w != 0L)
|
||||
{
|
||||
var bits = TrailingZerosCnt(w);
|
||||
w = Asn1Util.UrShift(w, bits);
|
||||
num4 += bits;
|
||||
}
|
||||
|
||||
len += buffer.EncodeIntValue(w);
|
||||
|
||||
var num7 = buffer.EncodeIntValue(num4);
|
||||
len += num7;
|
||||
|
||||
var num8 = RealBinary;
|
||||
|
||||
if (num3 == -1)
|
||||
{
|
||||
num8 |= PlusInfinity;
|
||||
}
|
||||
|
||||
switch (num7)
|
||||
{
|
||||
case RealExplen2:
|
||||
break;
|
||||
|
||||
case RealExplen3:
|
||||
num8 |= 1;
|
||||
break;
|
||||
|
||||
case RealExplenLong:
|
||||
num8 |= 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
num8 |= 3;
|
||||
len += buffer.EncodeIntValue(num7);
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.Copy((byte)num8);
|
||||
len++;
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
if (Value == 0.0)
|
||||
{
|
||||
outs.EncodeLength(0);
|
||||
}
|
||||
else if (Value == double.NegativeInfinity)
|
||||
{
|
||||
outs.EncodeIntValue(MinusInfinity, true);
|
||||
}
|
||||
else if (Value == double.PositiveInfinity)
|
||||
{
|
||||
outs.EncodeIntValue(PlusInfinity, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var len = 1;
|
||||
var num2 = BitConverter.DoubleToInt64Bits(Value);
|
||||
var num3 = ((num2 >> RealIso6093Mask) == 0L) ? 1 : -1;
|
||||
var num4 = ((int)((num2 >> 0x34) & 0x7ffL)) - 0x433;
|
||||
var w = (num4 == 0) ? ((num2 & 0xfffffffffffffL) << 1) : ((num2 & 0xfffffffffffffL) | 0x10000000000000L);
|
||||
|
||||
if (w != 0L)
|
||||
{
|
||||
var bits = TrailingZerosCnt(w);
|
||||
w = Asn1Util.UrShift(w, bits);
|
||||
num4 += bits;
|
||||
len += Asn1Util.GetUlongBytesCount(w);
|
||||
}
|
||||
else
|
||||
{
|
||||
len++;
|
||||
}
|
||||
|
||||
var num7 = RealBinary;
|
||||
|
||||
if (num3 == -1)
|
||||
{
|
||||
num7 |= PlusInfinity;
|
||||
}
|
||||
|
||||
var bytesCount = Asn1Util.GetBytesCount(num4);
|
||||
len += bytesCount;
|
||||
|
||||
switch (bytesCount)
|
||||
{
|
||||
case RealExplen2:
|
||||
break;
|
||||
|
||||
case RealExplen3:
|
||||
num7 |= 1;
|
||||
break;
|
||||
|
||||
case RealExplenLong:
|
||||
num7 |= 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
num7 |= 3;
|
||||
len++;
|
||||
break;
|
||||
}
|
||||
|
||||
outs.EncodeLength(len);
|
||||
outs.WriteByte((byte)num7);
|
||||
|
||||
if ((num7 & 3) == 3)
|
||||
{
|
||||
outs.EncodeIntValue(bytesCount, false);
|
||||
}
|
||||
|
||||
outs.EncodeIntValue(num4, false);
|
||||
outs.EncodeIntValue(w, false);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Equals(double value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var real = value as Asn1Real;
|
||||
|
||||
if (real == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Value == real.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
|
||||
private static int TrailingZerosCnt(long w)
|
||||
{
|
||||
var num = Asn1RunTime.IntTrailingZerosCnt((int)w);
|
||||
|
||||
if (num >= RealBase16)
|
||||
{
|
||||
return (Asn1RunTime.IntTrailingZerosCnt((int)Asn1Util.UrShift(w, RealBase16)) + RealBase16);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RelativeOid.cs
vendored
Normal file
74
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RelativeOid.cs
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1RelativeOid : Asn1ObjectIdentifier
|
||||
{
|
||||
public new static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RelativeOidTypeCode);
|
||||
|
||||
|
||||
public Asn1RelativeOid()
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1RelativeOid(OidValue oidValue)
|
||||
: base(oidValue)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
OidValue = OidValue.FromArray(buffer.DecodeRelOidContents(len));
|
||||
buffer.TypeCode = RelativeOidTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (OidValue.Items.Length < 1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
var len = 0;
|
||||
|
||||
for (var i = OidValue.Items.Length - 1; i >= 0; i--)
|
||||
{
|
||||
len += buffer.EncodeIdentifier(OidValue.Items[i]);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
foreach (var i in OidValue.Items)
|
||||
{
|
||||
len += Asn1RunTime.GetIdentBytesCount(i);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(len);
|
||||
|
||||
foreach (var i in OidValue.Items)
|
||||
{
|
||||
outs.EncodeIdentifier(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RunTime.cs
vendored
Normal file
151
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RunTime.cs
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public static class Asn1RunTime
|
||||
{
|
||||
public const int LicBer = 1;
|
||||
public const int LicPer = 2;
|
||||
public const int LicXer = 4;
|
||||
public const long Bit0Mask = -9223372036854775808L;
|
||||
|
||||
public static long DecodeIntValue(Asn1DecodeBuffer buffer, int length, bool signExtend)
|
||||
{
|
||||
var num = 0L;
|
||||
|
||||
if (length > 8)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1IntegerValueIsTooLarge);
|
||||
}
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var num2 = buffer.ReadByte();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
if ((i == 0) && signExtend)
|
||||
{
|
||||
num = (num2 > 0x7f) ? -1 : 0;
|
||||
}
|
||||
|
||||
num = (num * 0x100L) + num2;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public static int GetIdentBytesCount(long ident)
|
||||
{
|
||||
if (ident < 0x80L)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ident < 0x4000L)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ident < 0x200000L)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (ident < 0x10000000L)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (ident < 0x800000000L)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (ident < 0x40000000000L)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (ident < 0x2000000000000L)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (ident < 0x100000000000000L)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 9;
|
||||
}
|
||||
|
||||
public static int GetLongBitCount(long ivalue)
|
||||
{
|
||||
var num = ivalue & Bit0Mask;
|
||||
var num2 = 0;
|
||||
|
||||
if (ivalue != 0L)
|
||||
{
|
||||
while ((ivalue & Bit0Mask) == num)
|
||||
{
|
||||
num2++;
|
||||
ivalue = ivalue << 1;
|
||||
}
|
||||
|
||||
if (num == Bit0Mask)
|
||||
{
|
||||
num2--;
|
||||
}
|
||||
|
||||
return (0x40 - num2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetLongBytesCount(long value)
|
||||
{
|
||||
var num = 0x7f80000000000000L;
|
||||
var num2 = 8;
|
||||
|
||||
if (value < 0L)
|
||||
{
|
||||
value ^= -1L;
|
||||
}
|
||||
|
||||
while ((num2 > 1) && ((value & num) == 0L))
|
||||
{
|
||||
num = num >> 8;
|
||||
num2--;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
public static int GetUlongBytesCount(long value)
|
||||
{
|
||||
var number = -72057594037927936L;
|
||||
var num2 = 8;
|
||||
|
||||
while ((num2 > 1) && ((value & number) == 0L))
|
||||
{
|
||||
number = Asn1Util.UrShift(number, 8);
|
||||
num2--;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
public static int IntTrailingZerosCnt(int w)
|
||||
{
|
||||
return (0x20 -
|
||||
(((w & 0xffff) != 0)
|
||||
? (((w & 0xff) != 0) ? ((((w & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 0x18) : (((((w = Asn1Util.UrShift(w, 8)) & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 0x10))
|
||||
: ((((w = Asn1Util.UrShift(w, 0x10)) & 0xff) != 0) ? ((((w & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 8) : ((((w = Asn1Util.UrShift(w, 8)) & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))))));
|
||||
}
|
||||
}
|
||||
}
|
||||
7
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Status.cs
vendored
Normal file
7
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Status.cs
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public static class Asn1Status
|
||||
{
|
||||
public const int IndefiniteLength = -9999;
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1T61String.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1T61String.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1T61String : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, T61StringTypeCode);
|
||||
|
||||
public Asn1T61String()
|
||||
: base(T61StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1T61String(string data)
|
||||
: base(data, T61StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
108
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Tag.cs
vendored
Normal file
108
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Tag.cs
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Tag
|
||||
{
|
||||
public const short Universal = 0;
|
||||
public const short Private = 0xc0;
|
||||
public const short Application = 0x40;
|
||||
|
||||
public const short Bit8Mask = 0x80;
|
||||
public const short ClassMask = 0xc0;
|
||||
public const short CONS = 0x20;
|
||||
public const short CTXT = 0x80;
|
||||
public const bool EXPL = true;
|
||||
public const short EXTIDCODE = 0x1f;
|
||||
public const short FormMask = 0x20;
|
||||
public const short IDMask = 0x1f;
|
||||
public const bool IMPL = false;
|
||||
public const short L7BitsMask = 0x7f;
|
||||
public const short PRIM = 0;
|
||||
|
||||
public static readonly Asn1Tag Eoc = new Asn1Tag(0, 0, Asn1Type.EocTypeCode);
|
||||
public static readonly Asn1Tag Set = new Asn1Tag(0, 0x20, Asn1Type.SetTypeCode);
|
||||
public static readonly Asn1Tag Sequence = new Asn1Tag(0, 0x20, Asn1Type.SequenceTypeCode);
|
||||
public static readonly Asn1Tag Enumerated = new Asn1Tag(0, 0, Asn1Type.EnumeratedTypeCode);
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
public short Class;
|
||||
|
||||
[NonSerialized]
|
||||
public short Form;
|
||||
|
||||
[NonSerialized]
|
||||
public int IdCode;
|
||||
|
||||
|
||||
public Asn1Tag()
|
||||
{
|
||||
Class = 0;
|
||||
Form = 0;
|
||||
IdCode = 0;
|
||||
}
|
||||
|
||||
public Asn1Tag(short tagclass, short form, int idCode)
|
||||
{
|
||||
Class = tagclass;
|
||||
Form = form;
|
||||
IdCode = idCode;
|
||||
}
|
||||
|
||||
public virtual bool Constructed
|
||||
{
|
||||
get { return (Form == 0x20); }
|
||||
}
|
||||
|
||||
public bool Equals(Asn1Tag tag)
|
||||
{
|
||||
return Equals(tag.Class, tag.Form, tag.IdCode);
|
||||
}
|
||||
|
||||
public virtual bool Equals(short tagclass, short form, int idCode)
|
||||
{
|
||||
return ((Class == tagclass) && (IdCode == idCode));
|
||||
}
|
||||
|
||||
public virtual bool IsEoc()
|
||||
{
|
||||
return Equals(0, 0, 0);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.Append("[");
|
||||
|
||||
switch (Class)
|
||||
{
|
||||
case 0x80:
|
||||
break;
|
||||
|
||||
case Private:
|
||||
builder.Append("PRIVATE ");
|
||||
break;
|
||||
|
||||
case Universal:
|
||||
builder.Append("UNIVERSAL ");
|
||||
break;
|
||||
|
||||
case Application:
|
||||
builder.Append("APPLICATION ");
|
||||
break;
|
||||
|
||||
default:
|
||||
builder.Append("??? ");
|
||||
break;
|
||||
}
|
||||
|
||||
builder.Append(Convert.ToString(IdCode));
|
||||
builder.Append("]");
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
569
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Time.cs
vendored
Normal file
569
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Time.cs
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Time : Asn18BitCharString, IComparable
|
||||
{
|
||||
public const int January = 1;
|
||||
public const int February = 2;
|
||||
public const int March = 3;
|
||||
public const int April = 4;
|
||||
public const int May = 5;
|
||||
public const int June = 6;
|
||||
public const int July = 7;
|
||||
public const int August = 8;
|
||||
public const int September = 9;
|
||||
public const int October = 10;
|
||||
public const int November = 11;
|
||||
public const int December = 12;
|
||||
|
||||
public static readonly short[] DaysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
|
||||
public Asn1Time(short typeCode, bool useDerRules)
|
||||
: base(typeCode)
|
||||
{
|
||||
DerRules = useDerRules;
|
||||
Init();
|
||||
}
|
||||
|
||||
public Asn1Time(string data, short typeCode, bool useDerRules)
|
||||
: base(data, typeCode)
|
||||
{
|
||||
DerRules = useDerRules;
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected bool Parsed;
|
||||
|
||||
[NonSerialized]
|
||||
protected bool DerRules;
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int DiffHourValue;
|
||||
|
||||
public virtual int DiffHour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return DiffHourValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < -12) || (value > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DiffHourValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int DiffMinValue;
|
||||
|
||||
public virtual int DiffMinute
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return DiffMinValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected string SecFraction;
|
||||
|
||||
public virtual string Fraction
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return SecFraction;
|
||||
}
|
||||
set
|
||||
{
|
||||
SafeParseString();
|
||||
SecFraction = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int YearValue;
|
||||
|
||||
public virtual int Year
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return YearValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, value);
|
||||
}
|
||||
|
||||
if (!CheckDate(DayValue, MonthValue, value))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValueForDayAndMonth, value, DayValue, MonthValue);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
YearValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int MonthValue;
|
||||
|
||||
public virtual int Month
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return MonthValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 1) || (value > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, value);
|
||||
}
|
||||
|
||||
if (!CheckDate(DayValue, value, YearValue))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValueForDayAndYear, value, DayValue, YearValue);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
MonthValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int DayValue;
|
||||
|
||||
public virtual int Day
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return DayValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (((value < 1) || (value > 31)) || !CheckDate(value, MonthValue, YearValue))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValueForMonthAndYear, value, MonthValue, YearValue);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DayValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int HourValue;
|
||||
|
||||
public virtual int Hour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return HourValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 23))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
HourValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int MinuteValue;
|
||||
|
||||
public virtual int Minute
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return MinuteValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 59))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
MinuteValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int SecondValue;
|
||||
|
||||
public virtual int Second
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return SecondValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 59))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
SecondValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected bool UtcFlag;
|
||||
|
||||
public virtual bool Utc
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return UtcFlag;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!DerRules)
|
||||
{
|
||||
SafeParseString();
|
||||
UtcFlag = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual int CompareTo(object other)
|
||||
{
|
||||
if (other is DateTime)
|
||||
{
|
||||
var time2 = (DateTime)other;
|
||||
return (int)(GetTime().Ticks - time2.Ticks);
|
||||
}
|
||||
return (int)(GetTime().Ticks - ((Asn1Time)other).GetTime().Ticks);
|
||||
}
|
||||
|
||||
|
||||
protected static char CharAt(string s, int index)
|
||||
{
|
||||
if (index >= s.Length)
|
||||
{
|
||||
return '\0';
|
||||
}
|
||||
|
||||
return s[index];
|
||||
}
|
||||
|
||||
private static bool CheckDate(int day, int month, int year)
|
||||
{
|
||||
if ((day <= 0) || (month <= 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((year >= 0) && (month > 0))
|
||||
{
|
||||
int num = DaysInMonth[month];
|
||||
|
||||
if (((month == 2) && ((year % 4) == 0)) && (((year % 100) != 0) || ((year % 400) == 0)))
|
||||
{
|
||||
num++;
|
||||
}
|
||||
|
||||
if ((day >= 1) && (day <= num))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (month > 0)
|
||||
{
|
||||
if (day <= DaysInMonth[month])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((month == 2) && (day <= (DaysInMonth[month] + 1)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
YearValue = MonthValue = DayValue = HourValue = -1;
|
||||
MinuteValue = SecondValue = DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = DerRules;
|
||||
Parsed = true;
|
||||
SecFraction = "";
|
||||
Value = "";
|
||||
}
|
||||
|
||||
protected abstract bool CompileString();
|
||||
|
||||
protected override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
|
||||
{
|
||||
Parsed = false;
|
||||
base.Decode(buffer, explicitTagging, implicitLength, tag);
|
||||
DerRules = buffer is Asn1DerDecodeBuffer;
|
||||
}
|
||||
|
||||
protected override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
SafeParseString();
|
||||
|
||||
var flag = buffer is Asn1DerEncodeBuffer;
|
||||
|
||||
if (DerRules != flag)
|
||||
{
|
||||
DerRules = flag;
|
||||
|
||||
if (!CompileString())
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1TimeStringCouldNotBeGenerated);
|
||||
}
|
||||
}
|
||||
|
||||
return base.Encode(buffer, explicitTagging, tag);
|
||||
}
|
||||
|
||||
public virtual void Encode(Asn1BerOutputStream outs, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
SafeParseString();
|
||||
outs.EncodeCharString(Value, explicitTagging, tag);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value is Asn1Time)
|
||||
{
|
||||
return GetTime().Equals(((Asn1Time)value).GetTime());
|
||||
}
|
||||
|
||||
return ((value is DateTime) && GetTime().Equals((DateTime)value));
|
||||
}
|
||||
|
||||
public virtual int GetDiff()
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return ((DiffHourValue * 60) + DiffMinValue);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public virtual DateTime GetTime()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SecFraction))
|
||||
{
|
||||
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue, int.Parse(SecFraction));
|
||||
}
|
||||
|
||||
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue);
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
YearValue = MonthValue = DayValue = HourValue = -1;
|
||||
MinuteValue = SecondValue = 0;
|
||||
DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = DerRules;
|
||||
SecFraction = "";
|
||||
}
|
||||
|
||||
protected static int ParseInt(string str, IntHolder off, int len)
|
||||
{
|
||||
if ((off.Value + len) > str.Length)
|
||||
{
|
||||
throw ExceptionUtility.ArgumentOutOfRange("off");
|
||||
}
|
||||
|
||||
var mValue = off.Value;
|
||||
off.Value += len;
|
||||
|
||||
return int.Parse(str.Substring(mValue, len));
|
||||
}
|
||||
|
||||
public abstract void ParseString(string data);
|
||||
|
||||
protected virtual void PutInteger(int width, int value)
|
||||
{
|
||||
PutInteger(StringBuffer, width, value);
|
||||
}
|
||||
|
||||
public static void PutInteger(StringBuilder data, int width, int value)
|
||||
{
|
||||
var str = Convert.ToString(value);
|
||||
var length = str.Length;
|
||||
|
||||
if (length < width)
|
||||
{
|
||||
for (var i = length; i < width; i++)
|
||||
{
|
||||
data.Append('0');
|
||||
}
|
||||
}
|
||||
else if (length > width)
|
||||
{
|
||||
str = str.Substring(length - width);
|
||||
}
|
||||
|
||||
data.Append(str);
|
||||
}
|
||||
|
||||
protected virtual void SafeParseString()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetDiff(int inMinutes)
|
||||
{
|
||||
if (Math.Abs(inMinutes) > 720)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidDiffValue, inMinutes);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DiffHourValue = inMinutes / 60;
|
||||
DiffMinValue = inMinutes % 60;
|
||||
CompileString();
|
||||
}
|
||||
|
||||
public virtual void SetDiff(int dhour, int dminute)
|
||||
{
|
||||
if ((dhour < -12) || (dhour > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, dhour);
|
||||
}
|
||||
|
||||
if (Math.Abs(dminute) > 59)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, dminute);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DiffHourValue = dhour;
|
||||
|
||||
if (dhour < 0)
|
||||
{
|
||||
DiffMinValue = -Math.Abs(dminute);
|
||||
}
|
||||
else
|
||||
{
|
||||
DiffMinValue = Math.Abs(dminute);
|
||||
}
|
||||
|
||||
CompileString();
|
||||
}
|
||||
|
||||
public virtual void SetTime(DateTime time)
|
||||
{
|
||||
Clear();
|
||||
YearValue = time.Year;
|
||||
MonthValue = time.Month;
|
||||
DayValue = time.Day;
|
||||
HourValue = time.Hour;
|
||||
MinuteValue = time.Minute;
|
||||
SecondValue = time.Second;
|
||||
SecFraction = Convert.ToString(time.Millisecond);
|
||||
DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = DerRules;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
}
|
||||
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1TraceHandler.cs
vendored
Normal file
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1TraceHandler.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1TraceHandler : IAsn1NamedEventHandler
|
||||
{
|
||||
internal StreamWriter mPrintStream;
|
||||
|
||||
public Asn1TraceHandler()
|
||||
{
|
||||
mPrintStream = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding);
|
||||
mPrintStream.AutoFlush = true;
|
||||
}
|
||||
|
||||
public Asn1TraceHandler(StreamWriter ps)
|
||||
{
|
||||
mPrintStream = ps;
|
||||
}
|
||||
|
||||
public virtual void Characters(string svalue, short typeCode)
|
||||
{
|
||||
mPrintStream.WriteLine("data: " + svalue);
|
||||
}
|
||||
|
||||
public virtual void EndElement(string name, int index)
|
||||
{
|
||||
mPrintStream.Write(name);
|
||||
if (index >= 0)
|
||||
{
|
||||
mPrintStream.Write("[" + index + "]");
|
||||
}
|
||||
mPrintStream.WriteLine(": end");
|
||||
}
|
||||
|
||||
public virtual void StartElement(string name, int index)
|
||||
{
|
||||
mPrintStream.Write(name);
|
||||
if (index >= 0)
|
||||
{
|
||||
mPrintStream.Write("[" + index + "]");
|
||||
}
|
||||
mPrintStream.WriteLine(": start");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user